#include<bits/stdc++.h>
using namespace std;
vector<int> edge[200005];
int anc[20][200005]; // parent node
int level[200005], sbtr[200005]; // depth node dan jumlah node pada subtree
int in[200005], out[200005]; // buat cek subtree
int visited[200005], revcutter;
unordered_set<int> cutter; // cutter untuk menandai subtree yang membatasi jawaban, revcutter untuk menandai subtree yang
int lg = 18, timer, ans_dist, ans;
void dfs(int now, int par){
anc[0][now] = par; level[now] = level[par]+1;
visited[now] = 1;
in[now] = timer++;
for(int dst : edge[now]) if(dst != par) dfs(dst, now);
out[now] = timer++;
}
int last_dfs(int now, int par){
int x = 1;
for(int dst : edge[now]) if(dst != par && !cutter.count(dst) && (anc[0][revcutter] != dst)) x += last_dfs(dst, now);
return x;
}
void addEdge(int src, int dst){
edge[src].emplace_back(dst);
edge[dst].emplace_back(src);
}
int lca(int x, int y){
if(level[x] < level[y])
swap(x,y);
for(int i = lg; i >= 0; i--)
if((level[x] - (1 << i)) >= level[y])
x = anc[i][x];
if(x == y) return x;
for(int i = lg; i>=0; i--){
if(anc[i][x] != anc[i][y]){
x = anc[i][x]; y = anc[i][y];
}
}
return anc[0][x];
}
int distance(int x, int y){
return level[x] + level[y] - 2 * level[lca(x,y)];
}
// is y subtree of x
bool isSubtree(int x, int y){
return (in[x] <= in[y] && out[x] >= out[y]);
}
int solve(int x, int y){
if(x == y && !ans_dist) return x;
if(anc[18][x] != anc[18][y]) return 0;
bool stats = false;
int ancDepth = level[lca(x,y)];
int dist = distance(x,y);
int mid = (dist + ans_dist) >> 1, node;
for(auto element: cutter){
if(isSubtree(element, y)){
if(dist == ans_dist) return x;
return 0;
}
}
if(revcutter && !isSubtree(revcutter, y)){
if(dist == ans_dist) return x;
return 0;
}
if((level[x]+ans_dist+level[y])%2) {
return 0;
}
if(ans_dist != dist){
cutter.clear();
revcutter = 0;
}
else stats = true;
// cari dari y
if(mid == (level[y] - ancDepth)){
node = x;
int par = mid-1-ans_dist;
if(par != -1){
for(int i=lg; i>=0; i--){
if(par & (1 << i))
node = anc[i][node];
}
cutter.insert(node);
}
node = y;
for(int i=lg; i>=0; i--){
if((mid-1) & (1 << i))
node = anc[i][node];
}
cutter.insert(node);
ans_dist = mid;
}
else {
node = (mid > (level[y]-ancDepth))? x : y;
int par = mid-1-((node == x)?ans_dist:0);
if(par != -1){
for(int i=lg; i>=0; i--){
if(par & (1 << i)) {
node = anc[i][node];
}
}
cutter.insert(node);
}
revcutter = anc[0][node];
ans_dist = mid;
}
if(stats) return x;
return anc[0][node];
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
anc[0][0] = 0;
int n; cin >> n;
// while((1 << lg) < n)
// lg++;
int u,v,k;
for(int i=0;i<n-1;i++) {
cin >> u >> v >> k;
if(k) addEdge(u, v);
}
// binary lifting preprocessing
memset(visited, 0, sizeof(visited));
for(int i=1; i<=n; i++){
if(!visited[i]) dfs(i,i);
}
for(int i=1;i<=lg;i++){
for(int j=1;j<=n;j++){
anc[i][j] = anc[i-1][anc[i-1][j]];
}
}
int q; cin >> q;
int center; // jumlah node yang memenuhi dan tumpuan penghitungan node yang memenuhi
while(q--){
revcutter = 0, ans_dist = 0;
cutter.clear();
int peeps,x; cin >> peeps;
cin >> center;
cout << center << " ";
for(int i=0;i<(peeps-1);i++){
cin >> x;
cout << x << " ";
if(!center){
continue;
}
center = solve(center, x);
}
cout << ": ";
if(center){
cout << last_dfs(center, center) << '\n';
}
else cout << "0\n";
}
return 0;
}