// 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;
}