#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <sstream> #include <algorithm> #include <iostream> #include <iomanip> #include <map> #include <set> #include <list> #include <queue> #include <stack> #include <vector> #include <cassert> using namespace std; #define pb push_back #define mp make_pair #define REP(i, n) for (int i = 0; i < (int)(n); ++i) typedef long long LL; typedef pair<int, int> PII; struct S { int from, to, ind; S(int from, int to, int ind) : from(from), to(to), ind(ind) {} S() {} }; struct Cmp { bool operator()(const S &lhs, const S &rhs) const { return lhs.to < rhs.to; } }; int n, t; int a[250000]; vector<PII> g[250000]; set<S, Cmp> se; int dist[20][250000], cnt[250000] = {}, subCnt[250000] = {}, par[250000], dep[250000]; LL sum[250000] = {}, subSum[250000] = {}; vector<int> sub[250000]; int sz[250000]; bool used[250000]; inline void calcSizes(int v, int p) { sz[v] = 1; for (PII &to : g[v]) if (used[to.first] && to.first != p) { calcSizes(to.first, v); sz[v] += sz[to.first]; } } int calcDep; inline void cdCalc(int v, int p, int d) { dist[calcDep][v] = d; for (PII to : g[v]) if (used[to.first] && to.first != p) { cdCalc(to.first, v, d + to.second); } } void cdBuild(int v, int p) { calcSizes(v, -1); int tot = sz[v]; bool ok = false; int pp = -1; while (!ok) { ok = true; for (PII e : g[v]) { int to = e.first; if (used[to] && to != pp && sz[to] * 2 > tot) { pp = v; v = to; ok = false; break; } } } used[v] = false; if (p == -1) { dep[v] = 0; } else { dep[v] = dep[p] + 1; sub[p].pb(v); } par[v] = p; calcDep = dep[v]; cdCalc(v, -1, 0); for (PII to : g[v]) if (used[to.first]) { cdBuild(to.first, v); } } LL ans = 0; void addNode(int v) { ans += sum[v]; for (int i = dep[v] - 1, p = par[v], pp = v; i >= 0; --i) { ans += sum[p] - subSum[pp] + LL(cnt[p] - subCnt[pp]) * dist[i][v]; pp = p; p = par[p]; } ++cnt[v]; for (int i = dep[v] - 1, p = par[v], pp = v; i >= 0; --i) { ++cnt[p]; sum[p] += dist[i][v]; ++subCnt[pp]; subSum[pp] += dist[i][v]; pp = p; p = par[p]; } } void removeNode(int v) { --cnt[v]; for (int i = dep[v] - 1, p = par[v], pp = v; i >= 0; --i) { --cnt[p]; sum[p] -= dist[i][v]; --subCnt[pp]; subSum[pp] -= dist[i][v]; pp = p; p = par[p]; } } int q[1000000]; int main() { scanf("%d%d", &n, &t); REP(i, n - 1) { int from, to, w; scanf("%d%d%d", &from, &to, &w), --from, --to; g[from].pb(mp(to, w)); g[to].pb(mp(from, w)); } REP(i, n) used[i] = true; cdBuild(0, -1); REP(test, t) { int k; scanf("%d", &k); REP(i, k) scanf("%d", q + i), --q[i]; ans = 0; REP(i, k) addNode(q[i]); printf("%lld\n", ans); REP(i, k) removeNode(q[i]); } return 0; }