stablegradients/pie-gem5-bysrc huggingface dataset:
// Original C++ solution (slower):
#include <iostream>

#include <vector>

#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };



vector<edge> tree[MAX_V];

long long depth[MAX_V];



// v: 今いる頂点, p: v の親

void dfs(int v, int p, long long d) {

    depth[v] = d;

    for (int i = 0; i < tree[v].size(); i++) {

        edge e = tree[v][i];

        // 戻らないようにする処理

        if (e.to == p) { continue; }

        dfs(e.to, v, d + e.cost);

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K;

    dfs(K-1, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <vector>

#include <stack>



#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };

struct sets {int v, p; long long d; };

vector<edge> tree[MAX_V];

long long depth[MAX_V];



void dfs(int v, int p, long long d) {

    stack<sets> St;

    St.push(sets{v, p, d});



    while (!St.empty()) {

        sets cur = St.top(); St.pop();

        depth[cur.v] = cur.d;

        for (int i = 0; i < tree[cur.v].size(); i++) {

            edge e = tree[cur.v][i];

            if (e.to == cur.p) { continue; }

            St.push(sets{e.to, cur.v, cur.d + e.cost});

        }

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--, b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K; K--;

    dfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <vector>

#include <queue>



#define MAX_V 100001



using namespace std;



struct edge { int to; long long cost; };

struct sets { int v, p; long long d; };

vector<edge> tree[MAX_V];

long long depth[MAX_V];



void bfs(int v, int p, long long d) {

    queue<sets> q;

    q.push(sets{v, p, d});



    while (!q.empty()) {

        sets cur = q.front(); q.pop();

        depth[cur.v] = cur.d;

        for (int i = 0; i < tree[cur.v].size(); i++) {

            edge e = tree[cur.v][i];

            if (e.to == cur.p) { continue; }

            q.push(sets{e.to, cur.v, cur.d + e.cost});

        }

    }

}



int main() {

    int N, a, b, c;

    int Q, K, x, y;



    cin >> N;



    for (int i = 0; i < N-1; i++) {

        cin >> a >> b >> c;

        a--; b--;

        tree[a].push_back(edge{b, c});

        tree[b].push_back(edge{a, c});

    }



    cin >> Q >> K; K--;

    bfs(K, -1, 0);



    for (int i = 0; i < Q; i++) {

        cin >> x >> y;

        x--; y--;

        cout << depth[x] + depth[y] << endl;

    }

    return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <algorithm>

#include <vector>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <string>

#include <stack>

#include <queue>

#include <deque>

#include <map>

#include <set>



using namespace std;



typedef long long ll;

typedef pair<int, int> P;

const long long LINF = 1000000000000000018ll;

const int INF = 1000000009;

const int mod = 1000000007;



int v;

struct Edge {

  int dst;

  long long cost;

  Edge() {}

  Edge(int x, int y) : dst(x), cost(y) {}

};



vector<vector<Edge> > graph;

vector<long long> dijkstra(int start_v) {

  vector<long long> dist(v, 1000000000000000018ll);

  dist[start_v] = 0;

  priority_queue<pair<long long, int>, vector<pair<long long, int> >,

    greater<pair<long long, int> > > q;



  q.push(make_pair(0, start_v));



  while (!q.empty()) {

    pair<long long, int> t = q.top(); q.pop();

    int cur_v = t.second;

    for (int i = 0; i < graph[cur_v].size(); i++) {

      int next_v = graph[cur_v][i].dst;

      long long cost = graph[cur_v][i].cost;

      if (dist[next_v] > dist[cur_v] + cost) {

        dist[next_v] = dist[cur_v] + cost;

        q.push(make_pair(dist[next_v], next_v));

      }

    }

  }

  return dist;

}



int main() {

  cin.tie(0);

  ios::sync_with_stdio(false);

  cout << setprecision(20) << fixed;



  cin >> v;

  graph.assign(v, vector<Edge>());

  for (int i = 0; i < v-1; i++) {

    int src, dst, cost;

    cin >> src >> dst >> cost;

    src--; dst--;

    graph[src].push_back(Edge(dst, cost));

    graph[dst].push_back(Edge(src, cost));

  }

  int q, k;

  cin >> q >> k;

  vector<long long> dist = dijkstra(k-1);

  for (int i = 0; i < q; i++) {

    int x, y; cin >> x >> y;

    cout << dist[x-1] + dist[y-1] << endl;

  }

  return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <cstdio>

#include <string>

#include <algorithm>

#include <utility>

#include <cmath>

#include <vector>

#include <queue>

#define rep(i, n) for(int i = 0; i < n; i++)

using namespace std;

typedef long long ll;

ll mod = 1000000007;

const int Vmax = 100010;



struct edge {

    int to;

    ll weight;

};



vector<edge> tree[Vmax];

ll cost_k[Vmax];



void dfs(int v, int parent, ll dist) {

    cost_k[v] = dist;



    rep(i, tree[v].size()) {

        if(tree[v][i].to == parent) {

            continue;

        }

        dfs(tree[v][i].to, v, dist + tree[v][i].weight);

    }

}



int main() {

    int n;

    cin >> n;



    rep(i, n-1) {

        int a, b, c;

        cin >> a >> b >> c;

        a--;  b--;

        tree[a].push_back({b, c});

        tree[b].push_back({a, c});

    }



    int q, k;

    cin >> q >> k;

    k--;



    dfs(k, -1, 0);



    rep(i, q) {

        int x, y;

        cin >> x >> y;

        x--;  y--;

        cout << cost_k[x] + cost_k[y] << endl;

    }

    

    return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <cstdio>

#include <string>

#include <algorithm>

#include <utility>

#include <cmath>

#include <vector>

#include <queue>

#include <set>

#include <map>

#include <tuple>

#include <numeric>

#include <functional>

using namespace std;

typedef long long ll;

typedef vector<ll> vl;

typedef vector<vector<ll>> vvl;

typedef pair<ll, ll> P;

#define rep(i, n) for(ll i = 0; i < n; i++)

#define exrep(i, a, b) for(ll i = a; i <= b; i++)

#define out(x) cout << x << endl

#define exout(x) printf("%.10f\n", x)

#define chmax(x, y) x = max(x, y)

#define chmin(x, y) x = min(x, y)

#define all(a) a.begin(), a.end()

#define rall(a) a.rbegin(), a.rend()

#define pb push_back

#define re0 return 0

const ll mod = 1000000007;

const ll INF = 1e16;

const ll MAX_N = 100010;



int main() {

    ll n;

    cin >> n;

    

    vector<vector<P>> G(n);

    rep(i, n-1) {

        ll a, b, cost;

        cin >> a >> b >> cost;

        a--;  b--;

        G[a].pb(make_pair(b, cost));

        G[b].pb(make_pair(a, cost));

    }



    ll q, k;

    cin >> q >> k;

    k--;

    

    vl dist(n, -1);  // dist[v] : 頂点vの根からの距離

    queue<ll> Q;

    const ll root = k;

    dist[root] = 0;

    Q.push(root);

    while(!Q.empty()) {

        ll v = Q.front();

        Q.pop();

        for(auto p : G[v]) {

            ll u = p.first;

            ll cost = p.second; 

            if(dist[u] != -1) {

                continue;

            }

            dist[u] = dist[v] + cost;

            Q.push(u);

        }

    }

    

    vl ans(q);

    rep(i, q) {

        ll x, y;

        cin >> x >> y;

        x--;  y--;

        ans[i] = dist[x] + dist[y];

    }



    rep(i, q) {

        out(ans[i]);

    }

    

    re0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <string>

#include <algorithm>

#include <vector>

#include <cmath>

#include <queue>

#include <map>

#include <set>

#include <bitset>

#include <functional>

using namespace std;



typedef long long ll;



vector<pair<ll, int>> edg[100003];

ll d[100003];



int main() {

	int n; cin >> n;

	for (int i = 0; i < n - 1; ++i) {

		int a, b; ll c; cin >> a >> b >> c;

		--a; --b;

		edg[a].push_back({ c, b });

		edg[b].push_back({ c, a });

	}

	int q, k; cin >> q >> k;

	--k;

	priority_queue<pair<ll, int> > que;

	for (int i = 0; i < n; ++i) d[i] = -1;

	que.push({ 0, k});

	while (!que.empty()) {

		ll dis = -que.top().first; int pos = que.top().second; que.pop();

		if (d[pos] >= 0) continue;

		d[pos] = dis;

		for (auto p : edg[pos]) {

			que.push({ -dis - p.first, p.second });

		}

	}

	for (int i = 0; i < q; ++i) {

		int x, y; cin >> x >> y;

		--x; --y;

		cout << d[x] + d[y] << endl;

	}

	return 0;

}


// Optimized solution to the same problem (faster):
#include <iostream>

#include <string>

#include <algorithm>

#include <vector>

#include <cmath>

#include <queue>

#include <map>

#include <unordered_map>

#include <set>

#include <functional>

#include <bitset>

#include <numeric>

#include <complex>

#include <iomanip>

#include <cassert>

#include <random>





int main() {

    int n; std::cin >> n;

    std::vector<std::vector<int>> edg(n);

    std::vector<std::vector<long long>> cost(n);

    for (int i = 0; i < n - 1; i++) {

        int a, b, c; std::cin >> a >> b >> c;

        a--; b--;

        edg[a].push_back(b);

        edg[b].push_back(a);

        cost[a].push_back(c);

        cost[b].push_back(c);

    }

    int q, k; std::cin >> q >> k;

    k--;

    std::vector<long long> dist(n, 1e18);

    std::priority_queue<std::pair<long long, int>> que;

    que.emplace(0, k);

    dist[k] = 0;

    while (!que.empty()) {

        int pos = que.top().second;

        que.pop();

        for (int i = 0; i < (int)edg[pos].size(); i++) {

            int u = edg[pos][i];

            long long c = cost[pos][i];

            if (dist[u] <= dist[pos] + c) continue;

            dist[u] = dist[pos] + c;

            que.emplace(-dist[u], u);

        }

    }

    while (q--) {

        int x, y; std::cin >> x >> y;

        x--; y--;

        std::cout << dist[x] + dist[y] << std::endl;

    }

    return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include<bits/stdc++.h>

using namespace std;

queue<pair<int,long long> > q;

int n,qu,k;

vector<pair<int,long long> > ga[100100];

int a,b;

long long c;

long long dist[100100];

int main(){

	//freopen("input.txt","r",stdin);

	//freopen("output.txt","w",stdout);

	ios::sync_with_stdio(false);

	cin.tie(NULL);

	cout.tie(NULL);

	cin>>n;

	for(int i=1;i<n;i++){

		cin>>a>>b>>c;

		ga[a].push_back(make_pair(b,c));

		ga[b].push_back(make_pair(a,c));

		dist[i]=1e18;

	}

	cin>>qu>>k;

	memset(dist,63,sizeof(dist));

	q.push(make_pair(k,0LL));

	dist[k]=0LL;

	while(!q.empty()){

		int x=q.front().first;

		long long di=q.front().second;

		q.pop();

		if(di!=dist[x])

			continue;

		for(int i=0;i<ga[x].size();i++){

			int y=ga[x][i].first;

			long long cst=ga[x][i].second;

			if(dist[y]>di+cst){

				dist[y]=di+cst;

				q.push(make_pair(y,dist[y]));

			}

		}

	}

	while(qu--){

		cin>>a>>b;

		cout<<dist[a]+dist[b]<<endl;

	}

	return 0;

}




// Optimized solution to the same problem (faster):
// In the name of God



#include <bits/stdc++.h>



using namespace std;



const int N = 1e5+5;



long long d[N];

vector<pair<int,int>> adj[N];



int main() {

	ios_base::sync_with_stdio(false);

	cin.tie(0);

	int n;

	cin >> n;

	for(int i = 0; i < n-1; i++) {

		int a, b, c;

		cin >> a >> b >> c;

		a--;

		b--;

		adj[a].push_back(make_pair(b, c));

		adj[b].push_back(make_pair(a, c));

	}

	int q, k;

	cin >> q >> k;

	k--;

	for(int i = 0; i < n; i++) d[i] = 1e16;

	d[k] = 0;

	priority_queue<pair<long long, int>> pq;

	pq.push(make_pair(0, k));

	while(!pq.empty()) {

		int now = pq.top().second;

		pq.pop();

		for(pair<int,int> pv : adj[now]) {

			if(d[pv.first] > d[now] + pv.second) {

				d[pv.first] = d[now] + pv.second;

				pq.push(make_pair(-d[pv.first], pv.first));

			}

		}

	}

	for(int i = 0; i < q; i++) {

		int u, v;

		cin >> u >> v;

		u--;

		v--;

		cout << d[u]+d[v] << "\n";

	}

	return 0;

}


// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <iostream>

#include <vector>

using namespace std;

using ll = long long;

const int limit = 100010;

using edge = struct{int to; ll cost;};

vector<edge> tree[limit];

ll depth[limit];



void dfs(int v, int p, ll d){

    depth[v] = d;

    for(auto &e : tree[v]){

        if(e.to == p) continue;

        dfs(e.to, v, d + e.cost);

    }

}



int main(){

    int n;

    cin >> n;



    for(int i = 0; i < n - 1; ++i){

        int a, b, c;

        cin >> a >> b >> c;

        a--, b--;

        tree[a].push_back({b, c});

        tree[b].push_back({a, c});

    }



    int q, k;

    cin >> q >> k;

    k--;



    dfs(k, -1, 0);



    for(int i = 0; i < q; ++i){

        int x, y;

        cin >> x >> y;

        x--, y--;

        cout << depth[x] + depth[y] << endl;

    }



    return 0;

}

// Optimized solution to the same problem (faster):
 #include "bits/stdc++.h"



using namespace std;



#define sp(x) cout<<setprecision(x);

#define FOR(i,a,b) for(int i=(a);i<(b);i++)

#define REP(i,n) FOR(i,0,n)

#define all(a) (a).begin(), (a).end()

#define inf 10000000

#define linf INT64_MAX*0.99

#define print(s) cout<<(s)<<endl

#define lint long long

#define yes "Yes"

#define no "No"



typedef pair<int, int> P;



struct edge{

    lint to, cost;

};



int main(){

    ios::sync_with_stdio(false);

    cin.tie(0);

    int n, q, k;

    cin >> n;

    vector<vector<edge>> G(n, vector<edge>(0));

    for(int i = 0; i < n - 1; ++i){

        lint a, b, c;

        cin >> a >> b >> c;

        --a; --b; //0インデックス

        edge e;

        e.cost = c;//入力した辺の重み

        e.to = b;//入力した辺が行く先

        G[a].push_back(e);//これらをa辺目のところに入れておく

        e.to = a;

        G[b].push_back(e);

    }

    cin >> q >> k;

    --k;

    vector<lint> d(n, -1); // 拡張店のkからの最短距離

    queue<int> que;

    que.push(k);

    d[k] = 0;

    while(!que.empty()){

        int s = que.front();//queの一番先頭（始めに入れたやつ）をｓとおく

        que.pop();//queの銭湯を削除

        for(auto &e : G[s]){// a = [1, 2, 3, 4]  for i, item in enumulate(a):

            if(e.to == s || d[e.to] != -1) continue;

            d[e.to] = d[s] + e.cost;

            que.push(e.to);

        }

    }

    for(int i = 0; i < q; ++i){

        int x, y;

        cin >> x >> y;

        --x; --y;

        cout << d[x] + d[y] << endl;

    }

    return 0;

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

using ll=long long;

using ld=long double;

using st=string;

using ch=char;

typedef pair<ll,ll> P;

typedef vector<ll> vl;

typedef vector<vl> vvl;

typedef vector<P> vP;

typedef vector<ch> vc;

typedef vector<vc> vvc;

#define FOR(i,a,b) for(ll i=a;i<b;i++)

#define rep(i,n) FOR(i,0,n)

#define ROF(i,a,b) for(ll i=a;i>=b;i--)

#define per(i,a) ROF(i,a,0)

const ll MOD=1000000007;

const ll MOD2=998244353;

const ld PI=acos(-1);

const ll INF=1e18;

st abc="abcdefghijklmnopqrstuvwxyz";

st ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct edge{ll to,cost;};



const ll MXN=100005;

vector<edge> G[MXN];

vector<bool> B(MXN,false);

vl ans(MXN);



void bfs(ll x,ll d){

  B[x]=true;

  ans[x]=d;

  ll k=G[x].size();

  rep(i,k){

    if(B[G[x][i].to]==false){

      bfs(G[x][i].to,G[x][i].cost+d);

    }

  }

}



  

int main() {

  cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);

  ll N;

  cin >> N;

  rep(i,N-1){

    ll a,b,c;

    cin >> a >> b >> c;

    a--;b--;

    G[a].push_back({b,c});

    G[b].push_back({a,c});

  }

  ll Q,K;

  cin >> Q >> K;

  K--;

  bfs(K,0);

  rep(i,Q){

    ll x,y;

    cin >> x >> y;

    x--;y--;

    cout << ans[x]+ans[y] << endl;

  }

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;



int main(){

  int n;

  scanf("%d", &n);

  vector<vector<pair<int, int>>> g(n);

  for(int i = 1; i < n; i++){

    int a, b, c;

    scanf("%d %d %d", &a, &b, &c);

    a--; b--;

    g[a].emplace_back(b, c);

    g[b].emplace_back(a, c);

  }

  int q, k;

  scanf("%d %d", &q, &k);

  k--;

  vector<long> dist(n);

  auto dfs = [&](int from, int at, long d, const auto& dfs) -> void {

    dist[at] = d;

    for(auto i : g[at]) if(i.first != from){

      dfs(at, i.first, d + i.second, dfs);

    }

  };

  dfs(-1, k, 0, dfs);

  for(int i = 0; i < q; i++){

    int a, b;

    scanf("%d %d", &a, &b);

    a--; b--;

    printf("%lld\n", dist[a] + dist[b]);

  }

}

// Fastest known solution for this problem:
// Original C++ solution (slower):
#include <bits/stdc++.h>

#define rep(i,n) for (int i = 0; i < (n); ++i)

#define all(v) v.begin(), v.end()

using namespace std;

typedef long long ll;

using edge = struct {int to; ll cost;};

vector<vector<edge>> tree(100010);

vector<ll> depth(100010);



void dfs(int v, int p, ll d){

	depth[v] = d;

	for(auto &e: tree[v]){

		if(e.to == p) continue;

		dfs(e.to, v, d + e.cost);

	}

}



int main() {

	

	int n;

	cin >> n;

	rep(i, n-1){

		int a, b, c;

		cin >> a >> b >> c;

		a--;

		b--;

		tree[a].push_back({b, c});

		tree[b].push_back({a, c});

	}

	int q, k;

	cin >> q >> k;

	k--;

	

	dfs(k, -1, 0);

	rep(i, q){

		int x, y;

		cin >> x >> y;

		x--;

		y--;

		cout << depth[x] + depth[y] << endl;

	}

	return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

#define rep(i,n) for (int i = 0; i < (n); ++i)

#define all(v) v.begin(), v.end()

using namespace std;

typedef long long ll;



struct edge {

    ll to;

    ll cost;

};



using P = pair<ll, ll>;	// <最短距離, 頂点の番号>

void dijkstra(vector<vector<edge>> &g, vector<ll> &dist, ll s) {

    priority_queue<P, vector<P>, greater<P> > que;

    dist.assign(dist.size(), 1LL<<60);

    dist[s] = 0;

    que.push(P(0, s));

    while (!que.empty()) {

        P p = que.top();

        que.pop();

        ll v = p.second;

        if (dist[v] < p.first) continue;

        for (ll i=0; i<g[v].size(); ++i) {

            edge e = g[v][i];

            if (dist[e.to] > dist[v] + e.cost) {

                dist[e.to] = dist[v] + e.cost;

                que.push(P(dist[e.to], e.to));

            }

        }

    }

}



int main() {

	ll n;

	cin >> n;

	vector<vector<edge>> g(n);

	rep(i, n-1) {

		ll a, b, c;

		cin >> a >> b >> c;

		a--; b--;

		g[a].push_back({b, c});

		g[b].push_back({a, c});

	}

	ll Q, k;

	cin >> Q >> k;

	k--;

	vector<ll> dist(n);

	dijkstra(g, dist, k);

	rep(q, Q) {

		ll x, y;

		cin >> x >> y;

		x--; y--;

		ll ans = dist[x] + dist[y];

		printf("%lld\n", ans);

	}

	return 0;

}

// Fastest known solution for this problem: