// Jai Shree Ram
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define ll long long
#define int long long
#define pb push_back
#define all(v) v.begin(),v.end()
#define endl "\n"
#define x first
#define y second
#define gcd(a,b) __gcd(a,b)
#define mem1(a) memset(a,-1,sizeof(a))
#define mem0(a) memset(a,0,sizeof(a))
#define sz(a) (int)a.size()
#define pii pair<int,int>
#define hell 1000000007
#define elasped_time 1.0 * clock() / CLOCKS_PER_SEC
template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.x>>a.y;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.x<<" "<<a.y;return out;}
template<typename T,typename T1>T maxs(T &a,T1 b){if(b>a)a=b;return a;}
template<typename T,typename T1>T mins(T &a,T1 b){if(b<a)a=b;return a;}
int solve(){
int n; cin >> n;
vector<vector<int>>g1(n + 1),g2(n + 1);
vector<vector<pii>>table(21,vector<pii>(2*n + 1));
for(int i = 2; i <= n; i++){
int u,v; cin >> u >> v;
g1[u].push_back(v);
g1[v].push_back(u);
}
for(int i = 2; i <= n; i++){
int u,v; cin >> u >> v;
g2[u].push_back(v);
g2[v].push_back(u);
}
vector<int>in(n + 1),h1(n + 1),h2(n + 1),LOG(2*n + 1);
for(int i = 2; i <= 2*n; i++){
LOG[i] = LOG[i/2] + 1;
}
int t = 0;
function<void(int,int)> dfs = [&](int u,int p){
in[u] = ++t;
h1[u] = h1[p] + 1;
table[0][t] = {h1[u],u};
for(auto i:g1[u]){
if(i != p){
dfs(i,u);
table[0][++t] = {h1[u],u};
}
}
};
dfs(1,1);
for(int x = 1; x <= 20; x++){
for(int i = 1; i + (1 << (x - 1)) <= 2*n; i++){
table[x][i] = min(table[x - 1][i],table[x - 1][i + (1 << (x - 1))]);
}
}
auto lca = [&](int u,int v) -> int{
int l = min(in[u],in[v]);
int r = max(in[u],in[v]);
int j = LOG[r - l + 1];
auto s = min(table[j][l],table[j][r - (1 << j) + 1]);
return s.x;
};
vector<int>s(n + 1);
function<void(int,int)> dfs2 = [&](int u,int p){
s[u] = 1;
h2[u] = h2[p] + 1;
for(auto i:g2[u]){
if(i != p){
dfs2(i,u);
s[u] += s[i];
}
}
};
dfs2(1,1);
int ans = 0;
vector<int>temp;
set<pair<int,int>>st;
int current_height = 0;
auto take_max = [&](int u){
if(st.size() > 0){
auto itr = st.upper_bound({in[u],n + 1});
if(itr != st.end()){
maxs(ans,lca(u,itr->y) + current_height);
}
if(itr != st.begin()){
itr--;
maxs(ans,lca(u,itr->y) + current_height);
}
}
};
function<void(int,int)> dfs_add = [&](int u,int p){
take_max(u);
temp.push_back(u);
for(auto i:g2[u]){
if(i != p){
dfs_add(i,u);
}
}
};
function<void(int,int,int)> dfs3 = [&](int u,int p,int clear){
int big = -1, mx = -1;
for(auto i:g2[u]){
if(i != p and mx < s[i]){
big = i;
mx = s[i];
}
}
for(auto i:g2[u]){
if(i != p and i != big){
dfs3(i,u,1);
}
}
if(big != -1){
dfs3(big,u,0);
}
current_height = h2[u];
take_max(u);
st.insert({in[u],u});
for(auto i:g2[u]){
if(i != p and i != big){
temp.clear();
dfs_add(i,u);
for(auto i:temp){
st.insert({in[i],i});
}
}
}
if(clear == 1){
st.clear();
}
};
dfs3(1,1,0);
cout << ans << endl;
return 0;
}
signed main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#ifdef SIEVE
sieve();
#endif
#ifdef NCR
init();
#endif
int t=1;cin>>t;
while(t--){
solve();
}
return 0;
}