#include <bits/stdc++.h> using namespace std; using ll = long long; long long readInt(long long l,long long r,char endd){ long long x=0; int cnt=0; int fi=-1; bool is_neg=false; while(true){ char g=getchar(); if(g=='-'){ assert(fi==-1); is_neg=true; continue; } if('0'<=g && g<='9'){ x*=10; x+=g-'0'; if(cnt==0){ fi=g-'0'; } cnt++; assert(fi!=0 || cnt==1); assert(fi!=0 || is_neg==false); assert(!(cnt>19 || ( cnt==19 && fi>1) )); } else if(g==endd){ if(is_neg){ x= -x; } assert(l<=x && x<=r); return x; } else { assert(false); } } } string readString(int l,int r,char endd){ string ret=""; int cnt=0; while(true){ char g=getchar(); assert(g!=-1); if(g==endd){ break; } cnt++; ret+=g; } assert(l<=cnt && cnt<=r); return ret; } long long readIntSp(long long l,long long r){ return readInt(l,r,' '); } long long readIntLn(long long l,long long r){ return readInt(l,r,'\n'); } string readStringLn(int l,int r){ return readString(l,r,'\n'); } string readStringSp(int l,int r){ return readString(l,r,' '); } long long P10(int x){ return x == 0 ? 1 : 10 * P10(x - 1); } template <typename T, typename R = long long> vector<T> readArr(int len, R l, R r){ vector<T> a(len); for(int i = 0; i < len; i++){ if(i + 1 < len){ a[i] = readIntSp(l, r); } else { a[i] = readIntLn(l, r); } } return a; } struct union_find { vector<int> parent; int n; union_find(int n) : n(n) { clear(); } inline void clear(){ parent.assign(n, -1); } inline int find(int u){ return (parent[u] < 0) ? u : parent[u] = find(parent[u]); } inline bool same(int u, int v){ return find(u) == find(v); } inline bool join(int u, int v){ u = find(u); v = find(v); if (u != v){ if (parent[u] > parent[v]) swap(u, v); parent[u] += parent[v]; parent[v] = u; } return u != v; } inline int size(int u){ return -parent[find(u)]; } }; struct forest { vector<pair<int,int>> edges; vector<vector<int>> to, lg_parents; vector<int> sub, color, parent, depth, pre, ord, in, out; int comps, n, lgn, C; forest(int n): n(n) { to.resize(n); sub.assign(n, 0); color.assign(n, 0); parent.resize(n); depth.assign(n, 0); in.resize(n); out.resize(n); } void add_edge(int u, int v){ int id = edges.size(); assert(id < n - 1); edges.push_back(make_pair(u, v)); to[u].push_back(id); to[v].push_back(id); } inline int adj(int u, int id){ return u ^ edges[id].first ^ edges[id].second; } void dfs(int u, int p){ pre.push_back(u); in[u] = C++; color[u] = comps; parent[u] = p; sub[u] = 1; for(int id : to[u]){ int v = adj(u, id); if(v == p) continue; depth[v] = depth[u] + 1; dfs(v, u); sub[u] += sub[v]; } out[u] = C; ord.push_back(u); } bool is_ancestor(int u, int v){ return in[u] <= in[v] && out[v] <= out[u]; } void dfs_all(){ comps = 0; C = 0; for(int i = 0; i < n; i++){ if(!color[i]){ ++comps; dfs(i, -1); } } } void build_parents(){ lgn = 0; while((1<<lgn) <= n) lgn++; lg_parents.assign(lgn, vector<int>(n, -1)); for(int i = 0; i < n; i++) lg_parents[0][i] = parent[i]; for(int i = 1; i < lgn; i++){ for(int j = 0; j < n; j++){ if(~lg_parents[i - 1][j]){ lg_parents[i][j] = lg_parents[i - 1][lg_parents[i - 1][j]]; } } } } int jump(int u, int k){ for(int i = lgn - 1; i >= 0; i--) if(k&(1<<i)) u = lg_parents[i][u]; return u; } int lca(int u, int v){ if(depth[u] < depth[v]) swap(u, v); for(int i = lgn - 1; i >= 0; i--) if((depth[u] - depth[v])&(1<<i)) u = lg_parents[i][u]; if(u == v) return u; for(int i = lgn - 1; i >= 0; i--) if(lg_parents[i][u] != lg_parents[i][v]){ u = lg_parents[i][u]; v = lg_parents[i][v]; } return lg_parents[0][u]; } int dist(int u, int v){ return depth[u] + depth[v] - 2 * depth[lca(u, v)]; } }; int main(){ int t = readIntLn(1, 10); for(int ct = 1; ct <= t; ct++){ int n = readIntSp(1, P10(5)); int k = readIntLn(1, n); auto good = readArr<int>(k, 1, n); for(int & v : good) v--; union_find uf(n); forest fo(n); vector<vector<int>> adj(n); for(int i = 1; i < n; i++){ int u = readIntSp(1, n); int v = readIntLn(1, n); assert(u != v); u--; v--; assert(uf.join(u, v)); fo.add_edge(u, v); adj[u].push_back(v); adj[v].push_back(u); } fo.dfs_all(); fo.build_parents(); vector<ll> dist_sum(n); vector<int> sub(n); for(int v : good){ dist_sum[0] += fo.depth[v]; sub[v] = 1; } auto dfs = [&](auto self, int u, int p) -> void { for(int v : adj[u]){ if(v == p) continue; self(self, v, u); sub[u] += sub[v]; } }; dfs(dfs, 0, -1); auto fix = [&](auto self, int u, int p) -> void { if(p != -1){ dist_sum[u] = dist_sum[p]; dist_sum[u] -= sub[u]; dist_sum[u] += k - sub[u]; } for(int v : adj[u]){ if(v == p) continue; self(self, v, u); } }; fix(fix, 0, -1); int u = good[0], v = good[0], w = good[0]; for(int e : good) { if(fo.dist(u, e) > fo.dist(u, v)){ v = e; } } for(int e : good){ if(fo.dist(v, e) > fo.dist(v, w)){ w = e; } } for(int i = 0; i < n; i++){ dist_sum[i] -= max(fo.dist(i, v), fo.dist(i, w)); } int K = 0; for(int i = 0; i < n; i++){ if(dist_sum[i] <= dist_sum[K]){ K = i; } } cout << K + 1 << '\n'; } return 0; }