#include // ver2.7.1 #define int long long #define endl "\n" // fflush(stdout); #define ALL(v) (v).begin(),(v).end() #define Vi vector #define VVi vector #define VVVi vector #define Vm vector #define Vs vector #define Vd vector #define Vc vector #define Pii pair #define Pdd pair #define VPii vector #define Tiii tuple #define VTiii vector #define PQi priority_queue #define PQir priority_queue,greater> #define pb push_back #define mp make_pair #define mt make_tuple #define itos to_string #define stoi stoll #define FI first #define SE second #define cYES cout<<"YES"<()) #define rep(i,a,b) for(int i=a;i=b;i--) #define dem(a,b) ((a+b-1)/(b)) #define INF 3000000000000000000 // 3.0*10^18 #define MAX LLONG_MAX #define PI acos(-1.0L) int MOD = 998244353; // case //const int MOD = 1000000007; // 10^9 + 7 const double EPS = 1e-10; using namespace std; struct mint{int x;mint(int x=0):x((x%MOD+MOD)%MOD){} mint operator-()const{return mint(-x);} mint& operator+=(const mint a){if((x+=a.x)>=MOD)x-=MOD;return*this;} mint& operator-=(const mint a){if((x+=MOD-a.x)>=MOD)x-=MOD;return*this;} mint& operator*=(const mint a){(x*=a.x)%=MOD;return*this;} mint operator+(const mint a)const{return mint(*this)+=a;} mint operator-(const mint a)const{return mint(*this)-=a;} mint operator*(const mint a)const{return mint(*this)*=a;} mint pow(int t)const{if(!t)return 1;mint a=pow(t>>1);a*=a;if(t&1)a*=*this;return a;} mint inv()const{return pow(MOD-2);} mint& operator/=(const mint a){return*this*=a.inv();} mint operator/(const mint a)const{return mint(*this)/=a;}}; istream& operator>>(istream& is, const mint& a) {return is >> a.x;} ostream& operator<<(ostream& os, const mint& a) {return os << a.x;} /* debug */ template // vector ostream& operator<<(ostream& os,const vector &V){int N=V.size(); if(N==0){os<<'.';return os;}rep(i,0,N-1){os< // vector vector ostream& operator<<(ostream& os,const vector> &V){ int N=V.size();rep(i,0,N-1)cout< // pair ostream& operator<<(ostream& os, pair const&P){os< // set ostream& operator<<(ostream& os,set &S){auto it=S.begin();while(it!=S.end()){ os<<*it;if(next(it,1)!=S.end())os<<' ';it++;};return os;} template // deque ostream& operator<<(ostream& os, deque &q){for(auto it=q.begin();itvoid Vin(vector &v){int n=v.size();rep(i,0,n)cin>>v[i];} int gcd(int a,int b){return b?gcd(b,a%b):a;} int lcm(int a,int b){return a/gcd(a,b)*b;} int mypow(int x, int n, int m){ if(n==0)return 1;if(n%2==0)return mypow(x*x%m,n/2,m);else return x*mypow(x,n-1,m)%m;} int scomb(int n, int r){if(r<0||r>n)return 0;if((n-r)n-r;--i){a=a*i;}for(int i=1;i0){ret+=n%10;n/=10;}return ret;} int digit(int k,int i){string s = itos(k);return s[s.size()-i]-'0';} // i桁目の数字 templatevoid press(T &v){v.erase(unique(ALL(v)),v.end());} // 圧縮 Vi zip(Vi b){int Z=b.size(); // 座標圧縮 Pii p[Z+10];int a=b.size();Vi l(a);for(int i=0;i dep[v]) swap(u,v); for(int i=19;i>=0;i--) { if(((dep[v]-dep[u])>>i)&1) v = parII[v][i]; } if(u==v) return u; for(int i=19;i>=0;i--) { if(parII[u][i] != parII[v][i]){ u = parII[u][i]; v = parII[v][i]; } } return parII[u][0]; } void connect(int a,int b) { memot.pb(mp(a,b)); memot.pb(mp(b,a)); return; } void preset() { sort(ALL(memot)); rep(i,0,memot.size()) treeFI.pb(memot[i].FI); return; } void make(int root) { int st,en,now; int n = par.size(); par = Vi(n,-2); dep = par; chi = VVi(n,Vi(0)); par[root] = -1; dep[root] = 0; queue next; next.push(root); while(!next.empty()){ now = next.front(); next.pop(); st = lower_bound(ALL(treeFI), now)-treeFI.begin(); en = upper_bound(ALL(treeFI), now)-treeFI.begin(); rep(i,st,en){ if(par[memot[i].SE]!=-2) continue; next.push(memot[i].SE); chi[now].pb(memot[i].SE); par[memot[i].SE] = now; dep[memot[i].SE] = dep[now]+1; } } } void makechisize() { int n = par.size(); chisize = Vi(n,0); Vi chinasi(0); rep(i,0,n) if(chi[i].size()==0) chinasi.pb(i); VVi dev(n+5); rep(i,0,n) { dev[dep[i]].pb(i); } repreq(i,n+3,0){ rep(j,0,dev[i].size()){ if(par[dev[i][j]]==-1) continue; chisize[par[dev[i][j]]] += chisize[dev[i][j]]+1; } } return; } void makelongest() { int n = par.size(); longest = Vi(n,-1); Vi chinasi(0); rep(i,0,n) {if(chi[i].size()==0) chinasi.pb(i);} rep(i,0,chinasi.size()){ int now = chinasi[i]; int ct = 0; while(1) { if(longest[now] >= ct) break; else { longest[now] = ct; ct++; if(par[now] == -1) break; now = par[now]; } } } return; } /* 使い方 */ /* TreeAna tree(n) // 宣言 nは頂点数 tree.connect(a,b) // 頂点aとbをつなぐ(0-index) tree.preset() // 頂点をつなぎ終わったら必ずこれをする!!! tree.make(k) // 頂点kを根としてpar,dep,chiを作り上げる tree.makechisize(); // 頂点が持つ子の総数の配列 Vi chisize を作り上げる tree.makelongest(); // 頂点から何回下にいけるかのヤツ(Vi longest)を作り上げる tree.set_lca() // lcaを使う前に必ずこれをする!!! tree.lca(a,b) // 頂点aとbの共通の"先祖"で一番近い"頂点"を返す */ }; signed main() { cin.tie(0);cout.tie(0);ios::sync_with_stdio(false);cout<> n; TreeAna tree(n); map co; rep(i,0,n-1){ int qw,er,ty; cin >> qw >> er >> ty; qw--,er--; co[mp(qw,er)] = ty; co[mp(er,qw)] = ty; tree.connect(qw,er); } tree.preset(); tree.make(0); queue ne; ne.push(0); Vi wa(n); while(!ne.empty()){ int now = ne.front(); ne.pop(); rep(i,0,tree.chi[now].size()){ wa[tree.chi[now][i]] += co[mp(now,tree.chi[now][i])]+wa[now]; ne.push(tree.chi[now][i]); } } //cout << wa << endl; tree.set_lca(); int q;cin >> q; rep(i,0,q){ int qw,er; cin >> qw >> er; qw--,er--; int ty = tree.lca(qw,er); cout << wa[qw] + wa[er] - wa[ty]*2 << endl; } return 0; }