#include<bits/stdc++.h>
using namespace std;
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
// #define int long long
// #define ull unsigned long long
#define fi first
#define se second
#define pi pair<int,int>
const int N=1e6+10;
// const int INF=1e18;
const int mod=998244353;
int n;
int fa[N];
int sz[N];
int rt[N];
int xx[N],yy[N];
int ls[N*16],rs[N*16],tot=0;
int quickpow(int a,int b){
a%=mod;
long long ans=1;
while(b){
if(b&1) ans=ans*a%mod;
b>>=1;
a=1ll*a*a%mod;
}
return ans;
}
int find(int xt){
int x=xt;
while(fa[x]!=x){
x=fa[x];
}
while(fa[xt]!=xt){
xt=fa[xt];
fa[xt]=x;
}
return x;
}
void insert(int &t,int l,int r,int p){
// cerr<<"insert "<<l<<" "<<r<<" "<<t<<"\n";
if(!t) t=++tot;
if(tot>=N*16){
cout<l<<" "<<r<<"\n";
// cout<<"WAWAWA\n";
exit(0);
}
if(l==r){
return;
}
int mid=l+r>>1;
if(p<=mid) insert(ls[t],l,mid,p);
else insert(rs[t],mid+1,r,p);
}
bool ok=0;
int mergetree(int x,int y,int ll,int rr){
// cerr<<"merge "<<ll<<" "<<rr<<"\n";
if(!x||!y) return x+y;
if(ll==rr) {
// cerr<<"mt "<<ll<<" "<<rr<<"\n";
ok=1;
}
int mid=ll+rr>>1;
ls[y]=mergetree(ls[x],ls[y],ll,mid);
rs[y]=mergetree(rs[x],rs[y],mid+1,rr);
return y;
}
void merge(int x,int y){
int fx=find(x);
int fy=find(y);
mergetree(rt[fx],rt[fy],1,n);
// cout<<fx<<" "<<fy<<"\n";
if(fx==fy) return;
fa[fx]=fy;
sz[fy]+=sz[fx];
// cout<<fy<<"\n";
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
fa[i]=i;
sz[i]=1;
insert(rt[i],1,n,i);
}
bool can=1;
for(int i=1;i<n;i++){
cin>>xx[i]>>yy[i];
}
for(int i=1;i<n;i++){
int x,y;
cin>>x>>y;
insert(rt[x],1,n,y);
}
long long ans=1;
for(int i=1;i<n;i++){
ans*=1ll*quickpow(sz[find(xx[i])]*sz[find(yy[i])],mod-2);
ans%=mod;
ok=0;
merge(xx[i],yy[i]);
if(!ok) can=0;
}
if(!can){
cout<<0<<"\n";
return;
}
cout<<ans<<"\n";
}
signed main(){
IOS
int _=1;
// cin>>_;
while(_--){
solve();
}
}