// Slower C++ solution:
#include <iostream>

#include <vector>

#include <queue>



#define MAX_V 100001

#define INF 1e18



using namespace std;



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

typedef pair<long long, int> P;  // first は最短距離, second は頂点番号



vector<edge> tree[MAX_V];

long long d[MAX_V];

int N;



// s: 開始地点の頂点

void dijkstra(int s) {

    // greater<P> を指定することで first が小さい順に取り出せるようにする

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

    fill(d, d + N, INF);

    d[s] = 0;

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



    while (!que.empty()) {

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

        int v = p.second;

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

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

            edge e = tree[v][i];

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

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

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

            }

        }

    }

}



int main() {

    int 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--;



    dijkstra(K);



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

        cin >> x >> y;

        x--; y--;

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

    }

    return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.453644542811096x):
#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;

}