#![allow(unused_imports)]

use std::cmp::{max, min};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet, VecDeque};
use std::io::stdin;
use std::str::FromStr;

pub trait Graph<'a> {
    type NodeId: Copy;
    type Iter: Iterator<Item = Self::NodeId>;
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool;
    fn index(&self, a: Self::NodeId) -> usize;
    fn neighbors(&'a self, a: Self::NodeId) -> Self::Iter;
}

/// 重みありグラフ
pub type WeightedGraph<W> = Vec<Vec<(usize, W)>>;

impl<'a, W> Graph<'a> for WeightedGraph<W>
where
    W: std::marker::Copy + Clone + 'a,
{
    type NodeId = (usize, W);
    type Iter = std::iter::Cloned<std::slice::Iter<'a, Self::NodeId>>;

    fn len(&self) -> usize {
        self.len()
    }

    fn is_empty(&self) -> bool {
        self.len() == 0
    }

    fn index(&self, a: Self::NodeId) -> usize {
        a.0
    }

    fn neighbors(&'a self, a: Self::NodeId) -> Self::Iter {
        self[a.0].iter().cloned()
    }
}

/// 重み付き無向グラフ
pub fn make_weighted_undirected_graph<W: Clone>(
    n: usize,
    edges: &[(usize, usize, W)],
) -> WeightedGraph<W> {
    let mut g = vec![vec![]; n];
    for &(u, v, ref w) in edges.iter() {
        g[u].push((v, w.clone()));
        g[v].push((u, w.clone()));
    }
    g
}

fn main() {
    let n: usize = input().unwrap();
    let mut g = Vec::new();
    for i in 0..n - 1 {
        let (a, b, c): (usize, usize, usize) = input_three();
        g.push((a - 1, b - 1, c));
    }
    let g = make_weighted_undirected_graph(n, &g);

    let (q, k): (usize, usize) = input_two();

    let mut que = VecDeque::new();
    que.push_back((k - 1, k - 1, 0));

    let mut visited = vec![false; n];

    let mut dist = vec![std::usize::MAX; n];
    dist[k - 1] = 0;

    bfs(&g, &mut que, &mut dist, &mut visited);

    // dbg!(&dist);
    // dbg!(&visited);

    for _i in 0..q {
        let (x, y): (usize, usize) = input_two();
        println!("{}", dist[x - 1] + dist[y - 1]);
    }
}

fn bfs(
    g: &Vec<Vec<(usize, usize)>>,
    q: &mut VecDeque<(usize, usize, usize)>,
    dist: &mut Vec<usize>,
    v: &mut Vec<bool>,
) {
    let next = q.pop_front().unwrap();
    // dbg!(next);
    v[next.1] = true;
    dist[next.1] = dist[next.0] + next.2;

    for p in g[next.1].iter() {
        if v[p.0] == false {
            q.push_back((next.1, p.0, p.1));
        }
    }

    if q.is_empty() {
        return;
    }

    bfs(g, q, dist, v);
}

pub fn input<T: FromStr>() -> Result<T, T::Err> {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    Ok(buf.trim().parse().ok().unwrap())
}

pub fn input_vec<T: FromStr>() -> Result<Vec<T>, T::Err> {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    Ok(buf
        .trim()
        .split_whitespace()
        .map(|x| x.parse().ok().unwrap())
        .collect::<Vec<_>>())
}

pub fn input_two<T: FromStr, U: FromStr>() -> (T, U) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
    )
}

pub fn input_three<T: FromStr, U: FromStr, V: FromStr>() -> (T, U, V) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse::<T>().ok().unwrap(),
        s[1].parse::<U>().ok().unwrap(),
        s[2].parse::<V>().ok().unwrap(),
    )
}

pub fn input_four<T: FromStr, U: FromStr, V: FromStr, W: FromStr>() -> (T, U, V, W) {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    let s: Vec<&str> = buf.split_whitespace().collect();
    (
        s[0].parse().ok().unwrap(),
        s[1].parse().ok().unwrap(),
        s[2].parse().ok().unwrap(),
        s[3].parse().ok().unwrap(),
    )
}


Measured memory_bytes: 27896