// Original C++ solution (slower):
#include "bits/stdc++.h"

#pragma GCC optimize("Ofast")



// Begin {{{

using namespace std;



#ifndef DEBUG

#define dump(...)

#endif



template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }

template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }



template <class T>

inline vector<T> make_v(const T &initvalue, size_t sz) {

    return vector<T>(sz, initvalue);

}



template <class T, class... Args>

inline auto make_v(const T &initvalue, size_t sz, Args... args) {

    return vector<decltype(make_v<T>(initvalue, args...))>(sz, make_v<T>(initvalue, args...));

}



constexpr int INF = 0x3f3f3f3f;

constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;



using pii = pair<intmax_t, intmax_t>;

template <class T> using MaxHeap = priority_queue<T>;

template <class T> using MinHeap = priority_queue<T, vector<T>, greater<>>;



constexpr int dy[] = {0, 1, 0, -1, -1, 1, 1, -1};

constexpr int dx[] = {1, 0, -1, 0, 1, 1, -1, -1};



inline bool inside(int y, int x, int H, int W) {

    return (y >= 0 && x >= 0 && y < H && x < W);

}

// }}} End



size_t N;

vector<vector<pii>> G(int(1e5));



signed main() {

    ios_base::sync_with_stdio(false);

    cin.tie(nullptr);



    cin >> N;



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

        intmax_t a, b, c;

        cin >> a >> b >> c;

        a--, b--;

        G[a].emplace_back(b, c);

        G[b].emplace_back(a, c);

    }



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

    K--;



    MinHeap<pii> que;

    que.emplace(0, K);



    vector<intmax_t> dist(N, LINF);

    dist[K] = 0;



    while (!que.empty()) {

        intmax_t nowCost, nowNode;

        tie(nowCost, nowNode) = que.top();

        que.pop();

        for (auto nextNode: G[nowNode]) {

            if (chmin(dist[nextNode.first], dist[nowNode] + nextNode.second)) {

                que.emplace(dist[nextNode.first], nextNode.first);

            }

        }

    }



    dump(dist);



    while (Q--) {

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

        x--, y--;

        cout << dist[x] + dist[y] << "\n";

    }



    return 0;

}


// Optimized solution to the same problem (faster):
#include "bits/stdc++.h"



// Begin Header {{{

using namespace std;



#ifndef DEBUG

#define dump(...)

#endif



#define all(x) x.begin(), x.end()

#define rep(i, b, e) for (intmax_t i = (b), i##_limit = (e); i < i##_limit; ++i)

#define reps(i, b, e) for (intmax_t i = (b), i##_limit = (e); i <= i##_limit; ++i)

#define repr(i, b, e) for (intmax_t i = (b), i##_limit = (e); i >= i##_limit; --i)

#define var(Type, ...) Type __VA_ARGS__; input(__VA_ARGS__)



constexpr size_t    operator""_zu(unsigned long long value) { return value; };

constexpr intmax_t  operator""_jd(unsigned long long value) { return value; };

constexpr uintmax_t operator""_ju(unsigned long long value) { return value; };



constexpr int INF = 0x3f3f3f3f;

constexpr intmax_t LINF = 0x3f3f3f3f3f3f3f3f_jd;



template <class T, class Compare = less<>>

using MaxHeap = priority_queue<T, vector<T>, Compare>;

template <class T, class Compare = greater<>>

using MinHeap = priority_queue<T, vector<T>, Compare>;



inline void input() {}

template <class Head, class... Tail>

inline void input(Head&& head, Tail&&... tail) {

    cin >> head;

    input(forward<Tail>(tail)...);

}



template <class T>

inline istream& operator>>(istream &is, vector<T> &vec) {

    for (auto &e: vec) {

        is >> e;

    }

    return is;

}



inline void output() { cout << "\n"; }

template <class Head, class... Tail>

inline void output(Head&& head, Tail&&... tail) {

    cout << head;

    if (sizeof...(tail)) {

        cout << " ";

    }

    output(forward<Tail>(tail)...);

}



template <class T>

inline ostream& operator<<(ostream &os, const vector<T> &vec) {

    static constexpr const char *delim[] = {" ", ""};

    for (const auto &e: vec) {

        os << e << delim[&e == &vec.back()];

    }

    return os;

}



template <class T>

inline vector<T> makeVector(const T &initValue, size_t sz) {

    return vector<T>(sz, initValue);

}



template <class T, class... Args>

inline auto makeVector(const T &initValue, size_t sz, Args... args) {

    return vector<decltype(makeVector<T>(initValue, args...))>(sz, makeVector<T>(initValue, args...));

}



template <class Func>

class FixPoint : Func {

public:

    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}



    template <class... Args>

    constexpr decltype(auto) operator()(Args&&... args) const {

        return Func::operator()(*this, std::forward<Args>(args)...);

    }

};



template <class Func>

static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {

    return FixPoint<Func>{forward<Func>(f)};

}



template <class Container>

struct reverse_t {

    Container &c;

    reverse_t(Container &c) : c(c) {}

    auto begin() { return c.rbegin(); }

    auto end() { return c.rend(); }

};



template <class Container>

auto reversed(Container &c) {

    return reverse_t<Container>(c);

}



template <class T>

inline bool chmax(T &a, const T &b) noexcept {

    return b > a && (a = b, true);

}



template <class T>

inline bool chmin(T &a, const T &b) noexcept {

    return b < a && (a = b, true);

}



template <class T>

inline T diff(const T &a, const T &b) noexcept {

    return a < b ? b - a : a - b;

}

// End Header }}}



// Edge {{{

template <class Weight>

struct Edge {

    size_t from, to;

    Weight weight;



    Edge() {}

    Edge(size_t from, size_t to, Weight weight = 1) :

        from(from), to(to), weight(weight)

    {}



    bool operator<(const Edge &rhs) const {

        return weight < rhs.weight;

    }



    bool operator>(const Edge &rhs) const {

        return weight > rhs.weight;

    }



    operator size_t() const {

        return to;

    }

};

// }}}



// Graph {{{

template <class Weight>

class Graph : public vector<vector<Edge<Weight>>> {

    using graph = vector<vector<Edge<Weight>>>;



public:

    Graph() {}

    Graph(const size_t V) : graph(V) {}



    void connect(size_t from, size_t to, Weight weight = 1) {

        (*this)[from].emplace_back(from, to, weight);

    }



    friend ostream& operator<<(ostream &strm, const Graph &G) {

        for (size_t v = 0; v < G.size(); ++v) {

            strm << '[' << setw(2) << v << ']';

            for (const auto &e: G[v]) {

                strm << ' ' << setw(2) << e.to;

            }

            strm << '\n';

        }

        return strm;

    }

};

// }}}



// dijkstra {{{

template <class Weight>

vector<Weight> dijkstra(const Graph<Weight> &G, const vector<size_t> &startNodes) {

    using P = pair<Weight, size_t>;

    vector<Weight> dp(G.size(), numeric_limits<Weight>::max());

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



    for (const auto startNode: startNodes) {

        dp[startNode] = 0;

        pq.emplace(0, startNode);

    }



    while (!pq.empty()) {

        const Weight curCost = pq.top().first;

        const size_t curNode = pq.top().second;

        pq.pop();



        if (dp[curNode] < curCost) {

            continue;

        }



        for (const auto &e: G[curNode]) {

            const Weight newCost = dp[curNode] + e.weight;

            const size_t newNode = e.to;

            if (newCost < dp[newNode]) {

                dp[newNode] = newCost;

                pq.emplace(newCost, newNode);

            }

        }

    }



    return dp;

}

// }}}



signed main() {

    ios_base::sync_with_stdio(false);

    cin.tie(nullptr);



    var(size_t, N);



    Graph<intmax_t> G(N);

    rep(i, 0, N - 1) {

        var(size_t, a, b);

        var(intmax_t, c);

        a--, b--;

        G.connect(a, b, c);

        G.connect(b, a, c);

    }



    var(size_t, Q, K);

    K--;



    const auto dist = dijkstra(G, {K});

    while (Q--) {

        var(size_t, x, y);

        x--, y--;

        output(dist[x] + dist[y]);

    }



    return 0;

}


// Fastest known solution for this problem: