#include <algorithm>
#include <vector>
#include <unordered_map>
#include <queue>
#include <functional>
#include <climits>
#include <iostream>


class edge {
public:
	edge(int to, long long cost);
	int get_to() const;
	long long get_cost() const;
private:
	int to;
	long long cost;
};

edge::edge(int to, long long cost) : to(to), cost(cost) {}

int edge::get_to() const { return to; }

long long edge::get_cost() const { return cost; }


class dykstra {
private:
	//unordered_mapを使って隣接を構築
	//first:接続元、second:辺のコストと接続先
	std::unordered_map<int, std::vector<edge>> adj_list;
	int node_num;
	int start_point;
	std::vector<int> pred;//経路（遷移元）を保持
	std::vector<long long> costs;//距離を保持
	std::vector<bool> is_done;//確定ノードか否かを保持

public:
	dykstra(const int node_num, const std::unordered_map<int, std::vector<edge>>& adj_list);
	void calc_min_cost(int start);
	long long get_cost(int end) const;
	std::vector<int> get_min_path(int end) const;
};

dykstra::dykstra(const int node_num, const std::unordered_map<int, std::vector<edge>>& adj_list) :
	adj_list(adj_list),
	start_point(0),
	node_num(node_num),
	pred(node_num + 1, INT_MAX),
	costs(node_num + 1, LLONG_MAX),
	is_done(node_num + 1, false)
{}

void dykstra::calc_min_cost(int start) {
	this->start_point = start;
	this->pred = std::vector<int>(node_num + 1, INT_MAX);
	this->costs = std::vector<long long>(node_num + 1, LLONG_MAX);
	this->is_done = std::vector<bool>(node_num + 1, false);

	//優先度付きキューpairで頂点番号と最短距離を保持
	//firstの要素で比較されるので、firstが距離、secondを頂点番号とする
	std::priority_queue<std::pair<long long, int>,
		std::vector<std::pair<long long, int>>, std::greater<std::pair<long long, int>>> p_queue;
	p_queue.push(std::make_pair(0, start));
	pred[start] = -1;
	costs[start] = 0;

	while (1) {
		if (p_queue.empty() == true) break; //キューが空なら終了
		std::pair<long long, int> cost_node = p_queue.top();
		p_queue.pop();
		is_done[cost_node.second] = true; //キューから取り出した頂点を確定頂点とする
		for (auto &it : adj_list[cost_node.second]) {
			int adj_node = it.get_to();
			if (is_done[adj_node] == false) {
				long long adj_cost = it.get_cost() + cost_node.first;
				if (adj_cost < costs[adj_node]) {//計算された隣接頂点のコストが現在のコストより小さいなら
					costs[adj_node] = adj_cost; //隣接頂点のコストを更新
					pred[adj_node] = cost_node.second;//隣接頂点の遷移元を更新
					p_queue.push(std::make_pair(adj_cost, adj_node));//キューに隣接頂点の情報を突っ込む
				}
			}
		}
	}
}

long long dykstra::get_cost(int end) const {
	return costs[end];
}

std::vector<int> dykstra::get_min_path(int end) const {
	int node = end;
	std::vector<int> vec;
	vec.push_back(node);
	//終点から始点までの経路をたどる
	while (1) {
		//始点から辿れない頂点or
		//始点であれば終了
		if (pred[node] >= INT_MAX || pred[node] == -1) break;
		node = pred[node];
		vec.push_back(node);
	}
	std::reverse(vec.begin(), vec.end());
	return vec;
}

int main()
{
	std::unordered_map<int, std::vector<edge>> adj_list;
	int N;
	std::cin >> N;
	for (int i = 0; i < N - 1; i++) {
		int a, b;
		long long c;
		std::cin >> a>> b>>c;

		adj_list[a].push_back(edge(b, c));
		adj_list[b].push_back(edge(a, c));
		
	}
	int Q, K;
	dykstra d(N, adj_list);

	std::cin >> Q >> K;
	d.calc_min_cost(K);
	for (int i = 0; i < Q; i++) {
		int x, y;
		std::cin >> x >> y;
		std::cout << d.get_cost(x) + d.get_cost(y) << std::endl;
	}
    return 0;
}


Measured memory_bytes: 25880