#include using namespace std; using lint = long long; template using V = vector; template using VV = V< V >; namespace LCA { using T = lint; struct Edge { int to; T w; }; T op(const T& x, const T& y) { return x + y; } constexpr T e = 0; V<> dep; VV<> par; VV val; void init(const VV& g, int r) { int n = g.size(); dep.resize(n); par.assign(__lg(2 * n - 1), V<>(n, -1)); val.assign(__lg(2 * n - 1), V(n, e)); auto dfs = [&](const auto& dfs, int v, int p) -> void { for (const auto& e : g[v]) if (e.to != p) { dep[e.to] = dep[v] + 1; par[0][e.to] = v; val[0][e.to] = e.w; dfs(dfs, e.to, v); } }; dep[r] = 0; dfs(dfs, r, -1); for (int k = 1; k < (int) par.size(); ++k) { for (int v = 0; v < n; ++v) { if (par[k - 1][v] == -1) continue; par[k][v] = par[k - 1][par[k - 1][v]]; val[k][v] = op(val[k - 1][v], val[k - 1][par[k - 1][v]]); } } } int get_par(int v, int h) { for (int k = 0; h > 0; h >>= 1, ++k) { if (v == -1) break; if (h & 1) v = par[k][v]; } return v; } int lca(int u, int v) { if (dep[u] > dep[v]) swap(u, v); v = get_par(v, dep[v] - dep[u]); if (u == v) return u; for (int k = par.size() - 1; k >= 0; --k) { if (par[k][u] != par[k][v]) { u = par[k][u]; v = par[k][v]; } } return par[0][u]; } T get_val(int v, int h) { T res = e; for (int k = 0; h > 0; h >>= 1, ++k) { if (v == -1) break; if (h & 1) { res = op(res, val[k][v]); v = par[k][v]; } } return res; } T acc(int u, int v) { int a = lca(u, v); return op(get_val(v, dep[v] - dep[a]), get_val(u, dep[u] - dep[a])); } } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); int n; cin >> n; VV g(n); for (int _ = 0; _ < n - 1; ++_) { int u, v, w; cin >> u >> v >> w; g[u].emplace_back(LCA::Edge{v, w}); g[v].emplace_back(LCA::Edge{u, w}); } LCA::init(g, 0); int q; cin >> q; while (q--) { V<> x(3); for (auto&& e : x) cin >> e; sort(begin(x), end(x), [&](int u, int v) { return LCA::dep[u] < LCA::dep[v]; }); lint res = LCA::acc(x[1], x[2]); res += LCA::acc(x[0], LCA::lca(x[1], x[2])); cout << res << '\n'; } }