Meaning of the questions: to tree, the tree is complete between FIG ask Hamilton Cycle Number
We take into account the final Hamiltonian circuit must have a section of the tree to get the chain to string together
Each tree corresponding to the tree split into several pieces of chain, the number is not limited to the size limitation, all stitching together adjacent not required from the same tree
We can tree obtained into a tree number of program chains, where the direction of belt
Next, let's not consider the ring, only consider the sequence of problems have converted colors balls, each with a number of requirements, without seeking the final stitching together the same number of adjacent color
We handpicked for each color it has at least the same number to be adjacent to the inclusion-exclusion, we will merge the adjacent color stitching and other
direct construction of each color
, After the size of the combined enumeration
Consider the case of how to do the ring, the first force is the chain 1 is located, there are
:
Minus the illegal situation, the last Imperial on the first tree, then to subtract:
Violence ride up on it
Tree-DP, consider
represented by i to j is selected from the strands of the program number
0 represents
isolated,
represents i matches downwardly,
represents one path down through the upwardly
This is done in order to process
coefficients
#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 5e3 + 5;
int read(){
int cnt = 0, f = 1; char ch = 0;
while(!isdigit(ch)){ ch = getchar(); if(ch == '-') f = -1; }
while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();
return cnt * f;
}
int first[N], nxt[N << 1], to[N << 1], tot;
void adde(int x, int y){ nxt[++tot] = first[x], first[x] = tot, to[tot] = y; }
cs int Mod = 998244353, inv2 = (Mod+1)>>1;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod : a + b; }
int dec(int a, int b){ return a - b < 0 ? a - b + Mod : a - b; }
int mul(int a, int b){ return 1ll * a * b % Mod; }
void Add(int &a, int b){ a = add(a, b); }
void Mul(int &a, int b){ a = mul(a, b); }
int ksm(int a, int b){ int ans = 1; for(;b;b>>=1,a=mul(a,a)) if(b&1) ans = mul(ans, a); return ans; }
int fac[N], ifac[N]; int T, n, node;
int dp[N][N][3], sz[N];
int C(int n, int m){ if(n<0||m<0||n<m) return 0; return mul(fac[n], mul(ifac[m], ifac[n-m])); }
void prework(){
fac[0] = fac[1] = ifac[0] = ifac[1] = 1;
for(int i = 2; i <= N-5; i++) fac[i] = mul(fac[i-1], i);
ifac[N-5] = ksm(fac[N-5], Mod-2);
for(int i = N-6; i >= 2; i--) ifac[i] = mul(ifac[i+1], i+1);
}
void Merge(int u, int v){
int a = sz[u], b = sz[v]; sz[u] += sz[v];
static int tp[N][3]; memset(tp, 0, sizeof(int) * (a+b+1) * 3);
for(int i = 1; i <= b; i++){
int all = add(dp[v][i][0], add(dp[v][i][1], dp[v][i][2]));
for(int j = 1; j <= a; j++){
Add(tp[i + j][0], mul(dp[u][j][0], all));
Add(tp[i + j][1], mul(dp[u][j][1], all));
Add(tp[i + j][2], mul(dp[u][j][2], all));
Add(tp[i + j - 1][1], mul(dp[u][j][0], add(dp[v][i][1], mul(dp[v][i][0], 2))));
Add(tp[i + j - 1][2], mul(dp[u][j][1], add(dp[v][i][0], mul(dp[v][i][1], inv2))));
}
} memcpy(dp[u], tp, sizeof(int) * (a+b+1) * 3);
}
void dfs(int u, int fa){
memset(dp[u], 0, sizeof(int) * (sz[u] + 1) * 3); sz[u] = dp[u][1][0] = 1;
for(int i = first[u]; i; i = nxt[i]) if(to[i]^fa) dfs(to[i], u), Merge(u, to[i]);
}
int ans[N], G[N];
void PolyMul(int a, int b){
static int tmp[N + N];
memset(tmp, 0, sizeof(int) * (a+b-1));
for(int i = 0; i < a; i++) for(int j = 0; j < b; j++)
Add(tmp[i + j], mul(ans[i], G[j]));
memcpy(ans, tmp, sizeof(int) * (a+b-1));
}
int main(){
T = read(); ans[0] = 1; prework();
while(T--){
int k = read(); tot = 0; memset(first, 0, sizeof(int) * (k+1));
for(int i = 1; i < k; i++){ int x = read(), y = read(); adde(x, y); adde(y, x); }
dfs(1, 0); static int ct[N];
for(int i = 1; i <= k; i++)
ct[i] = mul(T==0?fac[i-1]:fac[i], add(dp[1][i][0], add(dp[1][i][1], dp[1][i][2])));
for(int i = 1; i <= k; i++){
int coef = 0;
for(int j = i; j <= k; j++){
int vl = mul(ct[j], C(j-1, i-1));
(j-i)&1 ? Add(coef, Mod-vl) : Add(coef, vl);
} if(T == 0){
G[i-1] = coef; if(i > 1) Add(G[i-2], Mod-coef);
} else G[i] = coef;
} if(T == 0) G[k] = 0; else G[0] = 0;
for(int i = 0; i <= k; i++) Mul(G[i], ifac[i]);
PolyMul(node+1, k+1); node += k;
} int sum = 0;
for(int i = 0; i <= node; i++) Add(sum, mul(fac[i], ans[i]));
cout << sum; return 0;
}