#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const int MAXN=1e5+5,MAXNUM=1300000;
int n;
vector<int>prime;
bool vis[MAXNUM];
class TREE{
private:
int sz[MAXN],maxson[MAXN];
vector<int>g[MAXN];
void init(){
centroid[0]=centroid[1]=-1;
for(int i=1;i<=n;i++){
g[i].clear();
}
}
ull hsh[MAXN];
void gethash(int x,int fa){
hsh[x]=1;
sz[x]=1;
for(auto it:g[x]){
if(it==fa) continue;
gethash(it,x);
hsh[x]+=hsh[it]*(ull)prime[sz[it]];
sz[x]+=sz[it];
}
}
public:
void buildtree(){
init();
for(int i=1,u,v;i<n;i++){
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
}
int centroid[2];
void getcentroid(int x,int fa){
sz[x]=1;
maxson[x]=0;
for(auto it:g[x]){
if(it==fa) continue;
getcentroid(it,x);
maxson[x]=max(maxson[x],sz[it]);
sz[x]+=sz[it];
}
maxson[x]=max(maxson[x],n-sz[x]);
if(maxson[x]<=n/2)
centroid[(centroid[0]==-1?0:1)]=x;
}
ull calchash(int rt){
gethash(rt,0);
return hsh[rt];
}
}t[2];
inline void solve(){
cin>>n;
t[0].buildtree();t[1].buildtree();
t[0].getcentroid(1,0);t[1].getcentroid(1,0);
if((t[0].centroid[1]==-1)^(t[1].centroid[1]==-1)){
puts("NO");
return;
}
if(t[0].calchash(t[0].centroid[0])==t[1].calchash(t[1].centroid[0])){
puts("YES");
}
else if(t[0].centroid[1]!=-1 && t[0].calchash(t[0].centroid[1])==t[1].calchash(t[1].centroid[0])){
puts("YES");
}
else{
puts("NO");
}
}
int main(){
for(int i=2;i<=MAXNUM;i++){
if(!vis[i]) prime.push_back(i);
if(prime.size()>=MAXN) break;
for(auto it:prime){
if(1LL*it*i>MAXNUM) break;
vis[it*i]=1;
if(i%it==0) break;
}
}
// cout<<prime.size()<<' '<<prime.back()<<endl;
int t;
cin>>t;
while(t--){
solve();
}
return 0;
}
树哈希,乘质数做法,代码中只有一个算重心时的 /2,一个素数筛时 %prime,其他地方没有涉及浮点数,为什么会SIGFPE,感激不尽