#include<iostream> #include<vector> usingnamespace std; constint N = 1e6+5; int pre[N];//并查集中的父节点 int father[N];// 最终树中某个节点的父节点 typedeflonglong LL; constint MOD = 998244353; pair<int,int> ope[N];//n-1次操作 vector<int> vec[N];//存储边的关系 int sz[N];//在每次合并时,sz[i]表示目前以i为根的块的数量s
intfind(int x){//并查集的找根操作 if(pre[x] == x) return x; elsereturn pre[x] = find(pre[x]); } voidjoin(int x,int y){//并查集的合并操作 int fx = find(x),fy = find(y); if(fx != fy){ sz[fy] = sz[fx] + sz[fy]; pre[fx] = fy; } return; } LL qp(LL a , LL b){//quick pow 快速幂 LL ans = 1ll; while(b){ if(b & 1){ ans = ans * a % MOD; } a = a * a % MOD; b >>=1; } return ans; } LL inv(LL x){//求逆元 returnqp(x,MOD-2); } //dfs来判断T树中的父亲关系 bool isgone[N]; voiddfs(int x){ for(int p : vec[x]){ if(!isgone[p]) { isgone[p] = true; father[p] = x; dfs(p); } } return; } intmain(){ int n; cin>>n; for(int i = 1;i<=n;i++) pre[i] = i; for(int i = 1;i<=n;i++) sz[i] = 1; int l , r; for(int i = 1;i<n;i++){ scanf("%d %d",&l,&r); ope[i] = {l,r}; } int u , v; for(int i = 1;i<n;i++){ scanf("%d %d",&u,&v); vec[u].push_back(v); vec[v].push_back(u); } isgone[1] = true; dfs(1);//令T变为以1为根节点的树 longlong sum = 1ll; for(int i = 1;i<n;i++){ int a = ope[i].first; int b = ope[i].second; if(find(father[find(a)]) == find(b)){ sum = sum *sz[find(a)] % MOD * sz[find(b)] % MOD; join(a,b); }elseif(find(father[find(b)]) == find(a)){ sum = sum *sz[find(a)] % MOD * sz[find(b)] % MOD; join(b,a); }else{ // cout<<a<<" "<<b<<endl; cout<<0; return0; } } // cout<<sum<<endl; cout<<inv(sum);