#include <bits/stdc++.h> using namespace std; typedef pair< int, int> ii; const int N = 1e5 + 5; int n, t, k, a[N], b[N], c[N]; vector< int > adj[N]; // hld int comp[N], sub[N], p[N], cntr, pos[N]; vector< vector< int > > val; void getSub(int v) { sub[v] = 1; for(int next : adj[v]) { if(next == p[v]) continue; int u = a[next] + b[next] - v; p[u] = next; getSub(u); sub[v] += sub[u]; } } void buildHLD(int v) { int sc, subsc, dist; sc = -1; subsc = 0; for(int next : adj[v]) { if(next == p[v]) continue; int u = a[next] + b[next] - v; if(subsc < sub[u]) { sc = u; subsc = sub[u]; dist = next; } } if(sc != -1) { pos[dist] = val[cntr].size(); val[cntr].push_back(dist); comp[dist] = cntr; buildHLD(sc); } for(auto next : adj[v]) if(next != p[v]) { int u = a[next]+b[next]-v; if(u == sc) continue; cntr++; val.push_back(vector< int > ()); comp[next] = cntr; pos[next] = 0; val[cntr].push_back(next); buildHLD(u); } } struct seg_tree { public: void build_tree(int ref) { n_ = val[ref].size(); sum.resize(n_+1); num.resize(n_<<2); lazy.resize(n_<<2); sum[0] = 0; for(int i = 0; i<n_; i++) { sum[i+1] = sum[i] + c[val[ref][i]]; } build(1, 0, n_); } void update(int x, int y, int v) { update_p(x, y+1, v, 1, 0, n_); } long long query(int x, int y) { // cout << x << " " << y << "q\n"; return (sum[y+1]-sum[x]) * k - ask(x, y+1, 1, 0, n_); } private: void build(int id, int l, int r) { num[id] = 0; lazy[id] = 0; if(r-l < 2) return; int mid = (l+r)>>1, il = id<<1, ir = il|1; build(il, l, mid); build(ir, mid, r); } void upd(int id, int l, int r, int v) { num[id] += v*(sum[r]-sum[l]); lazy[id] += v; } void shift(int id, int l, int r) { int mid = (l+r)>>1, il = id<<1, ir = il|1; upd(il, l, mid, lazy[id]); upd(ir, mid, r, lazy[id]); lazy[id] = 0; } void update_p(int x, int y, int v, int id, int l, int r) { if(l >= y || r <= x) return; if(l >= x && r <= y) { upd(id, l, r, v); // cout << l << " " << r << " " << num[id] << " upd\n"; return; } int mid = (l+r)>>1, il = id<<1, ir = il|1; shift(id, l, r); update_p(x, y, v, il, l, mid); update_p(x, y, v, ir, mid, r); num[id] = num[il] + num[ir]; // cout << l << " " << r << " " << num[id] << " " << v << " upd\n"; } long long ask(int x, int y, int id, int l, int r) { if(l >= y || r <= x) return 0; if(l >= x && r <= y) { return num[id]; } int mid = (l+r)>>1, il = id<<1, ir = il|1; shift(id, l, r); return ask(x, y, il, l, mid) + ask(x, y, ir, mid, r); } int n_; vector< long long > sum, num, lazy; }; vector< seg_tree > seg; void update(int u, int v) { while(1) { int now = p[u]; if(now < 0) break; seg[comp[now]].update(0, pos[now], v); now = val[comp[now]][0]; if(p[a[now]] != now) u = a[now]; else u = b[now]; } } long long query(int u) { long long ret = 0; while(1) { int now = p[u]; if(now < 0) break; ret += seg[comp[now]].query(0, pos[now]); now = val[comp[now]][0]; if(p[a[now]] != now) u = a[now]; else u = b[now]; } return ret; } int main() { scanf("%d%d", &n, &t); for(int i = 0; i<n-1; i++) { scanf("%d%d%d", a+i, b+i, c+i); a[i]--; b[i]--; adj[a[i]].push_back(i); adj[b[i]].push_back(i); } p[0] = -1; getSub(0); cntr = 0; val.push_back(vector< int > ()); buildHLD(0); cntr++; seg.resize(cntr); for(int i = 0; i<cntr; i++) seg[i].build_tree(i); while(t--) { map< int, int > mp; mp.clear(); scanf("%d", &k); for(int i = 0; i<k; i++) { int x; scanf("%d", &x); x--; mp[x]++; } for(auto it = mp.begin(); it != mp.end(); it++) { update(it->first, it->second); } long long ans = 0; for(auto it = mp.begin(); it != mp.end(); it++) { long long res = query(it->first); // cout << it-> first << " " << res << "\n"; ans += (it->second)*res; } printf("%lld\n", ans); for(auto it = mp.begin(); it != mp.end(); it++) { update(it->first, -(it->second)); } } return 0; }