#include using namespace std; template struct SparseTable { vector> st; vector lookup; SparseTable(const vector& v) { int b = 0; while ((1 << b) <= v.size()) b++; st.assign(b, vector(1 << b)); for (int i = 0; i < v.size(); i++) { st[0][i] = v[i]; } for (int i = 1; i < b; i++) { for (int j = 0; j + (1 << i) <= 1 << b; j++) { st[i][j] = min(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]); } } lookup.resize(v.size() + 1); for (int i = 2; i < lookup.size(); i++) { lookup[i] = lookup[i >> 1] + 1; } } T query(int l, int r) { int b = lookup[r - l]; return min(st[b][l], st[b][r - (1 << b)]); } }; struct LCA { int n, k = 0; vector> adj; vector vs, depth, id, D; SparseTable>* st; void dfs(int v, int p, int d) { id[v] = k; vs[k] = v; depth[k++] = d; D[v] = d; for (int s : adj[v]) { if (s != p) { dfs(s, v, d + 1); vs[k] = v; depth[k++] = d; } } } LCA(const vector>& adj) : n(adj.size()), adj(adj), vs(2 * adj.size() - 1), depth(2 * adj.size() - 1), id(adj.size()), D(adj.size()) { dfs(0, -1, 0); vector> ds; for (int i = 0; i < depth.size(); i++) { ds.emplace_back(depth[i], i); } st = new SparseTable>(ds); } int lca(int u, int v) { return vs[st->query(min(id[u], id[v]), max(id[u], id[v]) + 1).second]; } int dist(int u, int v) { return D[u] + D[v] - 2 * D[lca(u, v)]; } }; int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector>> adj(n); vector> adj2(n); for (int i = 0; i < n - 1; i++) { int a, b, w; cin >> a >> b >> w; adj[a].emplace_back(b, w); adj[b].emplace_back(a, w); adj2[a].push_back(b); adj2[b].push_back(a); } LCA lca(adj2); vector depth(n); function dfs = [&](int v, int p, long long d) { depth[v] = d; for (auto& s : adj[v]) { if (s.first != p) { dfs(s.first, v, d + s.second); } } }; dfs(0, -1, 0); int q; cin >> q; auto get_path_weight = [&](int a, int b) { return depth[a] + depth[b] - 2 * depth[lca.lca(a, b)]; }; while (q--) { int a, b, c; cin >> a >> b >> c; long long ans = 0; ans += get_path_weight(a, b); ans += get_path_weight(b, c); ans += get_path_weight(c, a); ans /= 2; cout << ans << '\n'; } }