// Slower C++ solution:
#include <bits/stdc++.h>

#define debug(x) cerr << #x << ": " << x << '\n';

using namespace std;

using ll = long long;

using P = pair<ll, int>;

const ll INF = (ll)1e17;



struct edge{

	int to, cost;

};



vector<edge> G[100010];

ll d[100010];



int main(void){

	int N; cin >> N;

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

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

		a--; b--;

		edge e; e.to = b; e.cost = c; G[a].push_back(e);

		e.to = a; G[b].push_back(e);

	}

	int Q, K; cin >> Q >> K;



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

	// 	printf("G[%d]: ", i);

	// 	for(auto& v: G[i]){

	// 		printf("%d ", v.to);

	// 	}

	// 	printf("\n");

	// }



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

	que.push(P(0, K-1));

	fill(d, d+N, INF); d[K-1] = 0;

	while(not que.empty()){

		P p = que.top(); que.pop();

		int v = p.second;

		// printf("#1\n");

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

		// printf("#2\n");

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

			edge e = G[v][i];

			// printf("e = {%d, %d}\n", e.to, e.cost);

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

				d[e.to] = d[v] + (ll)e.cost;

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

			}

		}

	}



	// for(int i = 0; i < N; i++) printf("d[%d] = %lld\n", i, d[i]);



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

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

		x--; y--;

		printf("%lld\n", (ll)d[x] + d[y]);

	}



	return 0;

}


// Faster C++ solution for the same problem (measured speedup: 3.4716162050454016x):
#include <bits/stdc++.h>

#define debug(x) cerr << #x << ": " << x << '\n';

using namespace std;

using ll = long long;

using P = pair<int, int>;

const int INF = (int)1e9;



// graph template

template<typename T>

class edge{

    public:

        int src, to; T cost;



        edge(int to, T cost): src(-1), to(to), cost(cost){}

        edge(int src, int to, T cost): src(src), to(to), cost(cost){}

};

template<typename T>

using Edges = vector<edge<T>>;

template<typename T>

using AdjacencyList = vector<Edges<T>>;

template<typename T>

using Matrix = vector<vector<T>>;



template<typename T>

vector<T> dijkstra(AdjacencyList<T> &g, int s){

    const auto INF = numeric_limits<T>::max();

    vector<T> dist(g.size(), INF);



    using Pr = pair<T, int>;

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

    dist[s] = 0;

    que.emplace(dist[s], s);



    while(not que.empty()){

        T cost; int v;

        tie(cost, v) = que.top(); que.pop();

        if(dist[v] < cost) continue;



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

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

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

                que.emplace(dist[e.to], e.to);

            }

        }

    }



    return dist;

}



int main(void){

    int N; 

    cin >> N;

    AdjacencyList<ll> G(N);

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

        int a, b, c;

        cin >> a >> b >> c;

        a--; b--;

        G[a].push_back(edge<ll>(b, c));

        G[b].push_back(edge<ll>(a, c));

    }



    int Q, K;

    cin >> Q >> K;

    vector<ll> dist = dijkstra(G, K-1);

    // for(int i = 0; i < N; i++) printf("dist[%d] = %lld\n", i, dist[i]);

    vector<ll> res(Q);

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

        int x, y;

        cin >> x >> y;

        x--; y--;

        res[i] = (dist[x] + dist[y]);

    }



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

        cout << res[i] << '\n';

    }



    return 0;

}