CodeEff/ECCO huggingface dataset:
# Original solution
from collections import defaultdict
def inpl(): return [int(i) for i in input().split()]

path = defaultdict(lambda: [])
N = int(eval(input()))
for _ in range(N-1):
    a, b, c = inpl()
    path[a].append((b,c))
    path[b].append((a,c))

Q, K = inpl()
now = {K}
dist = [0 for _ in range(N+1)]
visited = [False for _ in range(N+1)]
visited[K] = visited[0] = True
while True:
    for na in now.copy():
        na = now.pop()
        for nb, nc in path[na]:
            dist[nb] = dist[na] + nc
            visited[nb] = True
            path[nb].remove((na,nc))
            now.add(nb)
    if all(visited):
        break
for i in range(Q):
    x, y = inpl()
    print((dist[x]+dist[y]))

# Optimized solution
from collections import defaultdict
def inpl(): return [int(i) for i in input().split()]

path = defaultdict(lambda: [])
N = int(eval(input()))
for _ in range(N-1):
    a, b, c = inpl()
    path[a].append((b,c))
    path[b].append((a,c))

ctr = 1
Q, K = inpl()
now = [K]
dist = [0 for _ in range(N+1)]
while True:
    for na in now.copy():
        na = now.pop()
        for nb, nc in path[na]:
            dist[nb] = dist[na] + nc
            path[nb].remove((na,nc))
            now.append(nb)
            ctr += 1
    if ctr >=  N:
        break
for i in range(Q):
    x, y = inpl()
    print((dist[x]+dist[y]))
# Original solution
from collections import deque
N = int(eval(input()))
graph = [[] * N for _ in range(N)]
graph_dist = [[0] * N for _ in range(N)]
C = [0] * (N - 1)
for i in range(N-1):
    a, b, c = list(map(int, input().split()))
    a -= 1
    b -= 1
    graph[a].append(b)
    graph[b].append(a)
    graph_dist[a][b] = c
    graph_dist[b][a] = c

Q, K = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(Q)]

# BFSのためのデータ構造
dist = [-1 for _ in range(N)]   # 全頂点を未訪問に
que = deque()

# 初期条件(頂点 K-1 を初期ノードとする)
dist[K-1] = 0
que.append(K-1)

# BFS 開始(キューが空になるまで探索を行う)
while que:
    v = que[0]
    que.popleft()
    for new_v in graph[v]:
        if dist[new_v] != -1:   # すでに探索済みの頂点は探索しない
            continue
        # 新たな頂点 new_vについて距離情報を更新してキューに追加する
        dist[new_v] = dist[v] + graph_dist[v][new_v]
        que.append(new_v)


for i in range(Q):
    print((dist[xy[i][0] - 1] + dist[xy[i][1] - 1]))


# Optimized solution
from collections import deque
N = int(eval(input()))
graph = [[] * N for _ in range(N)]
for i in range(N-1):
    a, b, c = list(map(int, input().split()))
    a -= 1
    b -= 1
    graph[a].append([b, c])
    graph[b].append([a, c])
    
Q, K = list(map(int, input().split()))
xy = [list(map(int, input().split())) for _ in range(Q)]

# BFSのためのデータ構造
dist = [-1 for _ in range(N)]   # 全頂点を未訪問に
que = deque()

# 初期条件(頂点 K-1 を初期ノードとする)
dist[K-1] = 0
que.append(K-1)

# BFS 開始(キューが空になるまで探索を行う)
while que:
    v = que[0]
    que.popleft()
    for new_v_list in graph[v]:
        new_v = new_v_list[0]
        if dist[new_v] != -1:   # すでに探索済みの頂点は探索しない
            continue
        # 新たな頂点 new_vについて距離情報を更新してキューに追加する
        dist[new_v] = dist[v] + new_v_list[1]
        que.append(new_v)


for i in range(Q):
    print((dist[xy[i][0] - 1] + dist[xy[i][1] - 1]))
# Original solution
from heapq import heappush, heappop
from math import isinf


class Edge(object):

    def __init__(self, src, dst, cost):
        self.src = src
        self.dst = dst
        self.cost = cost


class Dijkstra(object):

    def __init__(self, v_len, edges, start, directed=False):
        """
        ダイクストラ法で最短経路を求める。

        :param v_len: グラフのノード数 通常は|V|、1-indexedなグラフなら |V| + 1
        :param edges: グラフの構造
        :param start: 始点 単一視点最短経路問題として解くので必要
        :param directed: 有向グラフの場合True 隣接行列を対称行列にするかが変わる
        """

        # 隣接行列 (adjacency matrix)
        # adj[i][j] でi番目の頂点からj番目の頂点へのコストを示す パスがなければINF
        self._adj = [[float('inf') for _ in range(v_len)] for _ in range(v_len)]
        for e in edges:
            self._adj[e.src][e.dst] = e.cost
            if not directed:
                self._adj[e.dst][e.src] = e.cost
        self._dist = [float('inf') for i in range(v_len)]  # 始点から各頂点までの最短距離
        self._prev = [float('inf') for i in range(v_len)]  # 最短経路における，その頂点の前の頂点のIDを格納する

        self._solve(start)

    def _solve(self, start):
        # 「最短距離が確定した頂点」に隣接する点からBFSするにあたり、それをどう探すかが問題になる
        # 安直に実装すればここで O(|V|) かかってしまうが、優先度キューを使えば O(log|V|) になる
        self._dist[start] = 0
        q = list()
        heappush(q, (0, start))  # キューの要素は (始点から頂点v_iへの仮の距離, v_iのID)

        while len(q) != 0:
            c, src = heappop(q)
            if self._dist[src] < c:
                continue

            # 隣接行列から隣接するノードを全て調べる = BFS
            for dst in range(len(self._adj)):
                cost = self._adj[src][dst]
                if isinf(cost):
                    continue
                if self._dist[src] + cost < self._dist[dst]:
                    self._dist[dst] = self._dist[src] + cost
                    heappush(q, (self._dist[dst], dst))
                    self._prev[dst] = src

    def distance(self, goal):
        return self._dist[goal]

    def path(self, goal):
        path = list()
        path.append(goal)
        cursor = goal

        while not isinf(self._prev[cursor]):
            path.append(self._prev[cursor])
            cursor = self._prev[cursor]

        return list(reversed(path))


N = int(eval(input()))
edges = list()
for _ in range(N - 1):
    a, b, c = list(map(int, input().split()))
    edges.append(Edge(a, b, c))

Q, K = list(map(int, input().split()))
dijkstra = Dijkstra(N + 1, edges, K)
for x, y in [tuple(map(int, input().split())) for _ in range(Q)]:
    print((dijkstra.distance(x) + dijkstra.distance(y)))


# Optimized solution
N = int(eval(input()))
nl = [list() for _ in range(N + 1)]
for _ in range(N - 1):
    a, b, c = list(map(int, input().split()))
    nl[a].append((b, c))
    nl[b].append((a, c))
Q, K = list(map(int, input().split()))

ans = [-1 for _ in range(N + 1)]
stack = [(K, -1, 0)]  # v, p, c
while len(stack) > 0:
    v, p, c = stack.pop()
    ans[v] = c
    for next_v, next_c in nl[v]:
        if next_v == p:
            continue
        stack.append((next_v, v, c + next_c))
for x, y in [tuple(map(int, input().split())) for _ in range(Q)]:
    print((ans[x] + ans[y]))
# Original solution
#!/usr/bin/env python3

import sys
import heapq

def main():
    input = sys.stdin.readline
    n = int(eval(input()))
    adjs = [[] for i in range(n)]
    for i in range(n - 1):
        a, b, c = list(map(int, input().split()))
        adjs[a - 1].append((b - 1, c))
        adjs[b - 1].append((a - 1, c))
    q, k = list(map(int, input().split()))

    # Dijkstra
    dist = [None] * n
    dist[k - 1] = 0
    hq = [(0, k - 1)]
    queued = [False] * n
    queued[k - 1] = True
    while hq:
        d, j = heapq.heappop(hq)
        dist[j] = d
        for j2, d2 in adjs[j]:
            if queued[j2]:
                continue
            heapq.heappush(hq, (d + d2, j2))
            queued[j2] = True

    # For each query
    for i in range(q):
        x, y = list(map(int, input().split()))
        print((dist[x - 1] + dist[y - 1]))

if __name__ == "__main__":
    main()


# Optimized solution
#!/usr/bin/env python3

import sys

def main():
    input = sys.stdin.readline
    n = int(eval(input()))
    adjs = [[] for i in range(n)]
    for i in range(n - 1):
        a, b, c = list(map(int, input().split()))
        adjs[a - 1].append((b - 1, c))
        adjs[b - 1].append((a - 1, c))
    q, k = list(map(int, input().split()))

    # DFS
    dist = [None] * n
    dist[k - 1] = 0
    hq = [(0, k - 1)]
    queued = [False] * n
    queued[k - 1] = True
    while hq:
        d, j = hq.pop()
        dist[j] = d
        for j2, d2 in adjs[j]:
            if queued[j2]:
                continue
            hq.append((d + d2, j2))
            queued[j2] = True

    # For each query
    for i in range(q):
        x, y = list(map(int, input().split()))
        print((dist[x - 1] + dist[y - 1]))

if __name__ == "__main__":
    main()
# Original solution
import heapq
import sys

sys.setrecursionlimit(10000)
INF = float('inf')

N = int(sys.stdin.readline())
ABC = [list(map(int, sys.stdin.readline().split())) for _ in range(N - 1)]
Q, K = list(map(int, sys.stdin.readline().split()))
X, Y = list(zip(*[list(map(int, sys.stdin.readline().split())) for _ in range(Q)]))


def dijkstra(graph, start):
    """
    TODO: start していしなかったときに全部の距離を知りたい

    マイナスの辺があっちゃダメ
    scipy.sparse.csgraph.dijkstra は内部で使われてるフィボナッチヒープが一部のケースでめっちゃ遅いのであんまり使わないほうがよさげ
    https://atcoder.jp/contests/soundhound2018-summer-qual/submissions/5311823

    :param list of (list of (int, int)) graph:
        graph[from_index]: (to_index, weight)
    :param int start:
    :return:
    """
    dist = [float('inf') for _ in range(len(graph))]
    dist[start] = 0
    heap = []
    heapq.heappush(heap, (0, start))

    while len(heap) > 0:
        w, v = heapq.heappop(heap)
        if w > dist[v]:
            continue
        for u, dw in graph[v]:
            if w + dw < dist[u]:
                dist[u] = w + dw
                heapq.heappush(heap, (w + dw, u))
    return dist


#: :type: list of (list of (int, int))
graph = [[] for _ in range(N + 1)]
for a, b, c in ABC:
    graph[a].append((b, c))
    graph[b].append((a, c))

dists = dijkstra(graph, K)

for x, y in zip(X, Y):
    print((int(dists[x] + dists[y])))


# Optimized solution
import sys

sys.setrecursionlimit(100000)
INF = float('inf')

N = int(sys.stdin.readline())
ABC = [list(map(int, sys.stdin.readline().split())) for _ in range(N - 1)]
Q, K = list(map(int, sys.stdin.readline().split()))
X, Y = list(zip(*[list(map(int, sys.stdin.readline().split())) for _ in range(Q)]))

#: :type: list of (list of (int, int))
graph = [[] for _ in range(N + 1)]
for a, b, c in ABC:
    graph[a].append((b, c))
    graph[b].append((a, c))

stack = [(K, 0)]
dists = {K: 0}
while stack:
    v, vw = stack.pop()
    for u, w in graph[v]:
        if u not in dists:
            dists[u] = vw + w
            stack.append((u, vw + w))

for x, y in zip(X, Y):
    print((int(dists[x] + dists[y])))
# Original solution
import heapq

N = int(eval(input()))
abc = [list(map(int,input().split())) for _ in range(N-1)]
Q,K = list(map(int,input().split()))
xy = [list(map(int,input().split())) for _ in range(Q)]

connect = [[] for _ in range(N)]
INFTY = 10**15
for a,b,c in abc:
    connect[a-1].append([b-1,c])
    connect[b-1].append([a-1,c])

cost = [[INFTY,False] for _  in range(N)]
cost[K-1][0] = 0
q = [(0,K-1)]
while q:
    _,i = heapq.heappop(q)
    if cost[i][1]:
        continue
    cost[i][1] = True
    ci0 = cost[i][0]
    for j,c in connect[i]:
        if cost[j][1]:
            continue
        tmp_cost = ci0+c
        if tmp_cost < cost[j][0]:
            cost[j][0] = tmp_cost
            heapq.heappush(q,(tmp_cost,j))

for x,y in xy:
    print((cost[x-1][0] + cost[y-1][0]))

# Optimized solution
N = int(eval(input()))
ABC = [list(map(int,input().split())) for _ in [0]*(N-1)]
Q,K = list(map(int,input().split()))
XY = [list(map(int,input().split())) for _ in [0]*Q]

E = [{} for _ in [0]*N]
for a,b,c in ABC:
    E[a-1][b-1] = c
    E[b-1][a-1] = c

def dist_dfs_tree(N,E,start):
    d = [-1]*N
    d[start] = 0
    q = [start]
    while q:
        i = q.pop()
        ci = d[i]
        for j,cj in list(E[i].items()):
            if d[j] !=-1:continue
            d[j] = ci+cj
            q.append(j)
    return d

d = dist_dfs_tree(N,E,K-1)
for x,y in XY:
    print((d[x-1]+d[y-1]))
# Original solution
import sys
import heapq
from operator import itemgetter
from collections import deque, defaultdict
from bisect import bisect_left, bisect_right
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)

class Heapq:
    def __init__(self, que=[], asc=True):
        if not asc:
            que = [-a for a in que]
        self.__que = que
        heapq.heapify(self.__que)
        self.__sign = 1 if asc else -1

    def pop(self):
        return heapq.heappop(self.__que) * self.__sign

    def push(self, value):
        heapq.heappush(self.__que, value * self.__sign)

    def pushpop(self, value):
        return heapq.heappushpop(self.__que, value * self.__sign) * self.__sign

    def top(self):
        return self.__que[0] * self.__sign

    def size(self):
        return len(self.__que)


def sol():
    N = int(eval(input()))
    edges = [[] for _ in range(N)]

    for _ in range(N - 1):
        fr, to, cost = list(map(int, input().split()))
        fr -= 1
        to -= 1
        edges[fr].append((to, cost))
        edges[to].append((fr, cost))

    Q, K = list(map(int, input().split()))
    K -= 1

    minDist = [float('inf')] * N
    que = Heapq([])
    que.push((0, K))

    while que.size():
        dist, now = que.pop()

        if minDist[now] < dist:
            continue
        minDist[now] = dist

        for to, cost in edges[now]:
            if minDist[to] > dist + cost:
                que.push((dist + cost, to))

    for _ in range(Q):
        fr, to = list(map(int, input().split()))
        print((minDist[fr - 1] + minDist[to - 1]))


sol()

# Optimized solution
from collections import deque
import sys
input = sys.stdin.buffer.readline

N = int(input())

edges = [[] for _ in range(N)]
for _ in range(N - 1):
    fr, to, cost = map(int, input().split())
    fr -= 1
    to -= 1
    edges[fr].append((to, cost))
    edges[to].append((fr, cost))

Q, K = map(int, input().split())
K -= 1
XY = [tuple(map(int, input().split())) for _ in range(Q)]

que = deque([(K, -1, 0)])
dist = [10**18] * N
while que:
    now, pr, d = que.popleft()
    dist[now] = d
    for to, c in edges[now]:
        if to == pr:
            continue
        que.append((to, now, d + c))

ans = [dist[x - 1] + dist[y - 1] for x, y in XY]
print(*ans, sep='\n')
# Original solution
N = int(input())
edges = [[] for _ in range(N)]

for _ in range(N - 1):
    fr, to, cost = map(int, input().split())
    fr -= 1
    to -= 1
    edges[fr].append((to, cost))
    edges[to].append((fr, cost))

Q, K = map(int, input().split())
K -= 1

minDist = [10**18] * N
minDist[K] = 0
st = [(K, 0)]
while st:
    now, dist = st.pop()
    for to, c in edges[now]:
        d = dist + c
        if minDist[to] > d:
            minDist[to] = d
            st.append((to, d))

ans = []
for _ in range(Q):
    X, Y = map(lambda a: int(a) - 1, input().split())
    ans.append(minDist[X] + minDist[Y])

print(*ans, sep='\n')


# Optimized solution
N = int(input())
edges = [[] for _ in range(N)]

for _ in range(N - 1):
    fr, to, cost = map(int, input().split())
    fr -= 1
    to -= 1
    edges[fr].append((to, cost))
    edges[to].append((fr, cost))

Q, K = map(int, input().split())
K -= 1
XY = [tuple(map(lambda a: int(a) - 1, input().split())) for _ in range(Q)]

minDist = [10**18] * N
minDist[K] = 0
st = [K]
while st:
    now = st.pop()
    dist = minDist[now]
    for to, c in edges[now]:
        d = dist + c
        if minDist[to] > d:
            minDist[to] = d
            st.append(to)

ans = [minDist[x] + minDist[y] for x, y in XY]
print(*ans, sep='\n')
# Original solution
import sys
sys.setrecursionlimit(100001)
def input():
    return sys.stdin.readline()[:-1]
from heapq import *

INF = 10 ** 20
def dijkstra(s, edges):
    dist = [INF for _ in range(len(edges))]
    dist[s], h = 0, []
    heappush(h, (0, s))
    while (len(h)):
        dv, v = heappop(h)
        if dv > dist[v]:
            continue
        for u, cost in edges[v]:
            if dv + cost < dist[u]:
                dist[u] = dv + cost
                heappush(h, (dist[u], u))
    return dist

N = int(eval(input()))
es = [[] for i in range(N+1)]
for i in range(N-1):
    a, b, c = list(map(int, input().split()))
    es[a].append((b, c))
    es[b].append((a, c))
Q, K = list(map(int, input().split()))
xy = [list(map(int, input().split())) for i in range(Q)]
dist = dijkstra(K, es)
for i in range(Q):
    print((dist[xy[i][0]] + dist[xy[i][1]]))


# Optimized solution
import sys
sys.setrecursionlimit(1000000)
def input():
    return sys.stdin.readline()[:-1]
from heapq import *

def dfs(s, es):
    dist = [None] * len(es)
    dist[s] = 0
    def ret(v, d):
        for u, c in es[v]:
            if dist[u] == None:
                dist[u] = dist[v] + c
                ret(u, dist[u])
    ret(s, 0)
    return dist
  
N = int(eval(input()))
es = [[] for i in range(N+1)]
for i in range(N-1):
    a, b, c = list(map(int, input().split()))
    es[a].append((b, c))
    es[b].append((a, c))
Q, K = list(map(int, input().split()))
xy = [list(map(int, input().split())) for i in range(Q)]
dist = dfs(K, es)
for i in range(Q):
    print((dist[xy[i][0]] + dist[xy[i][1]]))
# Original solution
import sys
# sys.setrecursionlimit(100000)
from collections import defaultdict


def warshall_floyd(graph: dict, N: int):
    """ graph:
    {node:{node:cost,node:cost,...},
     node:{node:cost,node:cost,...},...}
    """
    INF = float("inf")
    dp = [[INF] * N for _ in range(N)]
    for i in range(N):
        dp[i][i] = 0

    # Step 1: fill dp
    for v1, edges in list(graph.items()):
        for v2, cost in list(edges.items()):
            dp[v1][v2] = cost

    # search
    for k in range(N):  # 中継点
        for i in range(N):  # 始点
            for j in range(N):  # 終点
                dp[i][j] = min(dp[i][k] + dp[k][j], dp[i][j])

    return dp


def input():
    return sys.stdin.readline().strip()


def input_int():
    return int(eval(input()))


def input_int_list():
    return [int(i) for i in input().split()]


def main():
    n = input_int()
    graph = defaultdict(dict)
    for _ in range(n - 1):
        a, b, c = input_int_list()
        graph[a][b] = c
        graph[b][a] = c
    dp = warshall_floyd(graph, n + 1)
    q, k = input_int_list()
    ans = []
    for _ in range(q):
        x, y = input_int_list()
        ans.append(dp[x][k] + dp[k][y])

    for i in ans:
        print(i)

    return


if __name__ == "__main__":
    main()


# Optimized solution
import sys
# sys.setrecursionlimit(100000)
from collections import defaultdict
from heapq import heappop, heappush


class Dijkstra:
    """Graph input:
    {
    node:{node:cost,node:cost...},
    node:{node:cost,node:cost...},
    ...
    }
    """

    def __init__(self, graph: dict, N: int):
        self.graph = graph
        self.costs = [float("inf")] * N

    def calculate(self, start):
        queue = list()

        # step1: push the start point into the priority queue
        self.costs[start] = 0
        heappush(queue, (0, start))  # (cost,node)

        while queue:
            # step2: get the minimum cost node from unfixed node and fix the cost
            cost_from_start, min_node = heappop(queue)

            # step3: update the direct connected nodes
            for link, cost in list(self.graph[min_node].items()):
                if cost_from_start + cost < self.costs[link]:
                    self.costs[link] = cost_from_start + cost
                    heappush(queue, (self.costs[link], link))

        return self.costs


def input():
    return sys.stdin.readline().strip()


def input_int():
    return int(eval(input()))


def input_int_list():
    return [int(i) for i in input().split()]


def main():
    n = input_int()
    graph = defaultdict(dict)
    for _ in range(n - 1):
        a, b, c = input_int_list()
        graph[a][b] = c
        graph[b][a] = c
    # dp = warshall_floyd(graph, n + 1) O(n**3) => TLD

    q, k = input_int_list()

    solver = Dijkstra(graph, n + 1)
    costs = solver.calculate(k)

    ans = []
    for _ in range(q):
        x, y = input_int_list()
        ans.append(costs[x] + costs[y])
    for i in ans:
        print(i)

    return


if __name__ == "__main__":
    main()
# Original solution
n = int(eval(input()))
connect_list = [[] for i in range(n)]
for i in range(n-1):
    a, b, c = [ int(v)-1 for v in input().split() ]
    c += 1
    connect_list[a].append((b,c))
    connect_list[b].append((a,c))


q, k = [ int(v) for v in input().split() ]
k -= 1

shortest_list = [-1 for i in range(n)]
shortest_list[k] = 0

searching_list = [k]

while searching_list != []:

    new_search_list = []
    for i in searching_list:
        for j in connect_list[i]:
            x, y = j
            if shortest_list[x] == -1:
                shortest_list[x] = y + shortest_list[i]
                new_search_list.append(x)
    searching_list = new_search_list


for i in range(q):
    a, b = [ int(v)-1 for v in input().split() ]
    print((shortest_list[a] + shortest_list[b]))


# Optimized solution
import sys
input = sys.stdin.readline

n = int(eval(input()))
connect_list = [[] for i in range(n)]
for i in range(n-1):
    a, b, c = [ int(v)-1 for v in input().split() ]
    c += 1
    connect_list[a].append((b,c))
    connect_list[b].append((a,c))


q, k = [ int(v) for v in input().split() ]
k -= 1

shortest_list = [-1 for i in range(n)]
shortest_list[k] = 0

searching_list = [k]

while searching_list != []:

    new_search_list = []
    for i in searching_list:
        for j in connect_list[i]:
            x, y = j
            if shortest_list[x] == -1:
                shortest_list[x] = y + shortest_list[i]
                new_search_list.append(x)
    searching_list = new_search_list


for i in range(q):
    a, b = [ int(v)-1 for v in input().split() ]
    print((shortest_list[a] + shortest_list[b]))
# Original solution
n = int(eval(input()))
g = [[] for i in range(n)]
for i in range(n-1):
  a,b,c = list(map(int,input().split()))
  a-=1;b-=1
  g[a].append([b,c])
  g[b].append([a,c])
q,k = list(map(int,input().split()))
k -= 1
con = [-1] * n
con[k] = 0
stack = [k]
while stack:
  cur = stack.pop()
  for i,j in g[cur]:
    if con[i] == -1:
      con[i] = con[cur] + j
      stack.append(i)
for i in range(q):
  x,y = list(map(int,input().split()))
  x-=1;y-=1
  print((con[x]+con[y]))


# Optimized solution
import sys
input = sys.stdin.readline
n = int(eval(input()))
g = [[] for i in range(n)]
for i in range(n-1):
  a,b,c = list(map(int,input().split()))
  a-=1;b-=1
  g[a].append([b,c])
  g[b].append([a,c])
q,k = list(map(int,input().split()))
k -= 1
con = [-1] * n
con[k] = 0
stack = [k]
while stack:
  cur = stack.pop()
  for i,j in g[cur]:
    if con[i] == -1:
      con[i] = con[cur] + j
      stack.append(i)
for i in range(q):
  x,y = list(map(int,input().split()))
  x-=1;y-=1
  print((con[x]+con[y]))
# Original solution
n = int(eval(input()))
tree = [[] for _ in range(n+1)]

for i in range(n-1):
    a, b, c = list(map(int, input().split()))
    tree[a].append([b, c])
    tree[b].append([a, c])

q, k = list(map(int, input().split()))

from collections import deque
que = deque([k])
visit = [-1 for _ in range(n+1)]
visit[k] = 0
while que:
    pos = que.popleft()
    for i, j in tree[pos]:
        if visit[i] < 0:
            visit[i] = visit[pos]+j
            que.append(i)
for i in range(q):
    x, y = list(map(int, input().split()))
    print((visit[x]+visit[y]))

# Optimized solution
def main():
    n = int(eval(input()))
    tree = [[] for _ in range(n+1)]

    for i in range(n-1):
        a, b, c = list(map(int, input().split()))
        tree[a].append([b, c])
        tree[b].append([a, c])

    q, k = list(map(int, input().split()))

    from collections import deque
    que = deque([k])
    visit = [-1 for _ in range(n+1)]
    visit[k] = 0
    while que:
        pos = que.popleft()
        for i, j in tree[pos]:
            if visit[i] < 0:
                visit[i] = visit[pos]+j
                que.append(i)
    for i in range(q):
        x, y = list(map(int, input().split()))
        print((visit[x]+visit[y]))

if __name__=="__main__":
    main()