#include <bits/stdc++.h> #include <unordered_map> using namespace std; #define PII pair <int, int> int readInt () { bool minus = false; int result = 0; char ch; ch = getchar(); while (true) { if (ch == '-') break; if (ch >= '0' && ch <= '9') break; ch = getchar(); } if (ch == '-') minus = true; else result = ch-'0'; while (true) { ch = getchar();// if (ch < '0' || ch > '9') break; result = result*10 + (ch - '0'); } if (minus) return -result; else return result; } struct node { int parent; int poa; long long s, n, poadist; vector <PII> dist; node (int p, int pp){ poa = p; s = 0; n = 0; poadist = 0; parent = pp; dist.clear(); } }; int tot; const int MAXN = 100005; node * fn [MAXN]; vector <PII> edges [MAXN]; int vis [MAXN]; int sub [MAXN]; void dfs (int n, int p = 0){ tot++; sub [n] = 1; for (PII g : edges[n]){ if (g.first==p || vis[g.first]) continue; dfs (g.first, n); sub[n]+=sub[g.first]; } } int getl (int a, int b){ return (*(lower_bound(edges[a].begin(), edges[a].end(), PII(b, 0)))).second; } int gu [MAXN]; int findsep (int n, int p = 0){ int flag = (((tot - sub[n]) * 2) <= tot); for (PII g : edges[n]){ if (g.first == p || vis[g.first]) continue; if (sub[g.first] * 2 > tot){ flag = 0; break; } } if (flag) return n; for (PII g : edges[n]){if (g.first==p || vis[g.first]) continue; int k = findsep (g.first, n);if (k!=-1)return k;} return -1; } void df (int n, node *& x, int p = 0, int d = 0){ (x->dist).push_back(PII(n, d)); for (PII g : edges[n]){ if (vis[g.first] || g.first==p) continue; df (g.first, x, n, d + g.second); } } void sol (int nod, int p = 0){ tot = 0; dfs (nod); int K = findsep(nod); if (p!=0) gu[K] = getl (nod, p); fn[K] = new node (nod, p); df (nod, fn[K]); sort(fn[K]->dist.begin(), fn[K]->dist.end()); vis[K] = 1; for (PII g : edges[K]){ if (g.first==p || vis[g.first]) continue; sol (g.first, K); } } long long ans = 0; int gn (node * x){ return ((x==0)?(0):(x->n)); } long long gs (node * x){ if (x==NULL) return 0; return x->s; } long long gp (node * x){ if (x==NULL) return 0; return x->poadist; } vector <int> saw; int ad; int get (vector <PII> & a, int ad){ int lo = 0, hi = a.size() - 1; while (hi >= lo){ int mid = (hi + lo) / 2; if (a[mid].first > ad) hi = mid-1; else if (a[mid].first < ad) lo = mid + 1; else return a[mid].second; } return -1; } void add (node * &x, int node, int p = 0, long long d = 0){ if (x == NULL) return; saw.push_back(node) ; ans+=gs(x); if (p!=0){ ans-=gu[p] * gn(fn[p]); ans-=gp(fn[p]); } ans+=(gn(x) - gn(fn[p])) * d; int T = get(x->dist, ad); add (fn[x->parent], x->parent, node, T + gu[node]); x->n++; x->s+=d; x->poadist+=T; } int main() { int N, T; N = readInt(); T = readInt(); for (int g=0; g<N-1; g++){ int A, B, C; A = readInt(); B = readInt(); C = readInt(); edges[A].push_back(PII(B, C)); edges[B].push_back(PII(A, C)); } for (int g=1; g<=N; g++) sort(edges[g].begin(), edges[g].end()); sol (1); for (int g=0; g<T; g++){ ans = 0; int K; K = readInt(); saw.clear(); for (int y=0; y<K; y++){ int Z; Z = readInt(); ad = Z; add (fn[Z], Z); //cout << "DEAD "<< ans << "\n"; } for (int g : saw){ fn[g]->s = 0; fn[g]->n = 0; fn[g]->poadist = 0; } printf("%lld\n", ans); } return 0; }