void solve(){
int N, Q; cin >> N >> Q;
vector<vector<int>> links(N+1);
vector<pii> edges;
rep(i, 0, N-1){
int u, v; cin >> u >> v;
links[u].push_back(v);
links[v].push_back(u);
edges.push_back({u, v});
}
auto [ETT_in, ETT_out] = ETT(N, links);
vector<int> ETT_inv(N+1);
rep(i, 1, N+1) ETT_inv[ETT_in[i]] = i;
LCA_Tree = new Tree_LCA(N+1, links);
vector<Node> nodes(N+1);
rep(i, 1, N+1) nodes[i] = Node(ETT_inv[i], ETT_inv[i], 0);
SegmentTreeNode seg(N+1, nodes);
vector<int> edge_to_subtree(N-1);
rep(i, 0, N-1){
auto [u, v] = edges[i];
if(LCA_Tree->depth[u] < LCA_Tree->depth[v]) swap(u, v);
edge_to_subtree[i] = u;
}
while(Q--){
int K; cin >> K;
vector<int> cuts(K);
rep(i, 0, K) cin >> cuts[i];
vector<Node> Query_nodes;
vector<pair<int, bool>> events; // {ETT_idx, is_end}
for(auto c: cuts){
int u = edge_to_subtree[c-1];
events.push_back({ETT_in[u], false});
events.push_back({ETT_out[u], true});
}
sort(all(events));
int cur = 1;
stack<Node> stk;
stk.push(Node());
for(auto [idx, is_end]: events){
if(is_end){
Node& top = stk.top();
top = seg.pull(top, seg.query(cur, idx));
cur = idx+1;
Query_nodes.push_back(top);
stk.pop();
}
else{
Node& top = stk.top();
top = seg.pull(top, seg.query(cur, idx-1));
cur = idx;
stk.push(Node());
}
}
Node& top = stk.top();
top = seg.pull(top, seg.query(cur, N));
Query_nodes.push_back(top);
sort(all(Query_nodes), [](Node a, Node b){
return a.dist > b.dist;
});
int ans = 0;
if(Query_nodes.size() > 0) ans = Query_nodes[0].dist;
if(Query_nodes.size() > 1) ans = max(ans, (Query_nodes[0].dist+1)/2 + (Query_nodes[1].dist+1)/2 + 1);
if(Query_nodes.size() > 2) ans = max(ans, (Query_nodes[1].dist+1)/2 + (Query_nodes[2].dist+1)/2 + 2);
cout << ans << "\n";
}
}