#include using namespace std; using ll = long long; // #define int ll using PII = pair; #define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i) #define REP(i, n) FOR(i, 0, n) #define ALL(x) x.begin(), x.end() template T &chmin(T &a, const T &b) { return a = min(a, b); } template T &chmax(T &a, const T &b) { return a = max(a, b); } template bool IN(T a, T b, T x) { return a<=x&&x T ceil(T a, T b) { return a/b + !!(a%b); } template vector make_v(size_t a) { return vector(a); } template auto make_v(size_t a,Ts... ts) { return vector(ts...))>(a,make_v(ts...)); } template typename enable_if::value==0>::type fill_v(T &t, const V &v) { t=v; } template typename enable_if::value!=0>::type fill_v(T &t, const V &v ) { for(auto &e:t) fill_v(e,v); } template ostream &operator <<(ostream& out,const pair& a){ out<<'('< ostream &operator <<(ostream& out,const vector& a){ out<<'['; for(T i: a) {out< class sparseTable { public: using T = typename S::T; int n; vector log2; vector> t; sparseTable(int nn = 1e5) { init(nn); } void init(int nn) { n = nn; log2.assign(n+1, 0); for(int i=2; i<=n; ++i) log2[i] = log2[i >> 1] + 1; t.assign(log2[n]+1, vector(n)); } void build(vector v) { for(int i=0; i> par; vector> g; vector depth; // 頂点iの深さ vector vs; // 頂点を訪問順に並べたもの vector depth_seq; // depth_seq[i] = (頂点vs[i]の深さ) vector id; // 頂点が初めてvsに登場するインデックス sparseTable st; void dfs(int v, int p, int d, int &k) { id[v] = k; vs[k] = v; depth_seq[k++] = d; depth[v] = d; for(auto to: g[v]) if(to != p) { dfs(to, v, d+1, k); vs[k] = v; depth_seq[k++] = d; } } public: LCA(int n_=1e5) : n(n_), g(n), depth(n), vs(2*n-1), depth_seq(2*n-1), id(n) {} // u-vに辺を張る void add_edge(int u, int v) { g[u].push_back(v); g[v].push_back(u); } // rootを根として初期化 void build(int root = 0) { int k = 0; dfs(root, -1, 0, k); vector v(2*n-1); REP(i, 2*n-1) v[i] = {depth_seq[i], i}; st.init(2*n-1); st.build(v); } // uとvのlcaを返す O(1) int get(int u, int v) { if(id[u] > id[v]) swap(u, v); return vs[st.query(id[u], id[v]).second]; } }; struct auxiliaryTreeBasedLCA { ll cur; LCA lca; vector> g; vector depth, fs, ls; void dfs(ll v, ll p) { fs[v] = cur++; for(auto to: g[v]) { if(to == p) continue; depth[to] = depth[v] + 1; dfs(to, v); } ls[v] = cur-1; } auxiliaryTreeBasedLCA() {} auxiliaryTreeBasedLCA(ll n) : lca(n), g(n), depth(n), fs(n), ls(n) {} void add_edge(ll a, ll b) { lca.add_edge(a, b); g[a].push_back(b); g[b].push_back(a); } void build() { dfs(0, -1); lca.build(); } // 頂点集合vから作成されるグラフの辺集合を返す vector makeTree(vector v) { sort(ALL(v), [&](ll a, ll b){ return fs[a] < fs[b]; }); const int k = v.size(); REP(i, k-1) v.push_back(lca.get(v[i], v[i+1])); sort(ALL(v), [&](ll a, ll b){ return fs[a] < fs[b]; }); stack st; vector edges; int pre = -1; REP(i, (ll)v.size()) { if(pre == v[i]) continue; while(st.size() && ls[st.top()] < fs[v[i]]) st.pop(); if(st.size()) edges.push_back({st.top(), v[i]}); st.push(v[i]); pre = v[i]; } return edges; } }; signed main(void) { cin.tie(0); ios::sync_with_stdio(false); ll n; cin >> n; vector> g(n); auxiliaryTreeBasedLCA tree(n); REP(i, n-1) { ll a, b, c; cin >> a >> b >> c; g[a].push_back({b, c}); g[b].push_back({a, c}); tree.add_edge(a, b); } tree.build(); vector dist(n); function dfs = [&](ll v, ll p) { for(auto to: g[v]) { if(to.first == p) continue; dist[to.first] = dist[v] + to.second; dfs(to.first, v); } }; dfs(0, -1); ll q; cin >> q; while(q--) { ll k; cin >> k; vector v(k); REP(i, k) cin >> v[i]; auto edges = tree.makeTree(v); ll ret = 0; for(auto e: edges) { ret += dist[e.first] + dist[e.second] - 2*dist[tree.lca.get(e.first, e.second)]; } cout << ret << endl; } return 0; }