This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#pragma GCC optimize("O2")
#include<bits/stdc++.h>
#define ll long long
#define bit(mask, i) ((mask >> i) & 1)
using namespace std;
void __print(short x) {cerr << x;}
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}
template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ", "; __print(x.second); cerr << '}';}
template <typename... A>
void __print(const tuple<A...> &t) { bool first = true; cerr << '{'; apply([&first](const auto &...args) { ((cerr << (first ? "" : ","), __print(args), first = false), ...); }, t); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; for (auto &i: x) cerr << (f++ ? ", " : ""), __print(i);}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#define deb(x...) cerr << "\e[91m" << "[In "<<__func__<<"() : line " <<__LINE__<<" ] : [" << #x << "] = ["; _print(x); cerr << "\n\e[39m";
const ll INF = 1e18;
const int MOD = 1e9 + 7;
const int maxN = 1e5 + 5;
short LOG[maxN << 1];
struct RMQ {
  vector<vector<pair<int, int>>> rmq;
  RMQ() {};
  void build(const vector<pair<int, int>>& V) {
    int n = V.size();
    for (int i = 2; i <= n; ++i) LOG[i] = LOG[i >> 1] + 1;
    rmq.assign(25, V);
    int dep = 18;
    for (int i = 0; i < dep - 1; ++i)
      for (int j = 0; j < n; ++j) {
        rmq[i + 1][j] = min(rmq[i][j], rmq[i][min(n - 1, j + (1 << i))]);
      }
  }
  pair<int, int> query(int a, int b) {
    if (b <= a) return make_pair(INF, INF);
    int dep = LOG[b - a];
    return min(rmq[dep][a], rmq[dep][b - (1 << dep)]);
  }
};
int n, m, q, H;
vector<pair<int, int>> adj[maxN];
int C[maxN];
bool mark[maxN];
int cnt[maxN];
int depth[maxN], in[maxN], out[maxN];
int timer = 0;
ll res[maxN];
ll D[maxN];
ll dist[maxN];
struct LCA {
  RMQ rmq;
  vector<pair<int, int>> linear;
  LCA() {};
  LCA(int n) : linear(2 * n) {}
  bool in_subtree(int u, int v) {
    return in[u] <= in[v] && in[v] <= out[u];
  }
  void dfs(int u, int dep) {
    linear[timer] = {dep, u};
    in[u] = timer++;
    depth[u] = dep;
    cnt[u] = 1;
    for (auto [v, w] : adj[u]) {
      if (in[v] == -1) {
        dist[v] = dist[u] + w;
        dfs(v, dep + 1);
        cnt[u] += cnt[v];
        linear[timer++] = {dep, u};
      }
    }
    out[u] = timer;
  }
  void build(int root) {
    dfs(root, 0);
    rmq.build(linear);
  }
  int query(int a, int b) {
    a = in[a], b = in[b];
    return rmq.query(min(a, b), max(a, b) + 1).second;
  }
  ll get_dist(int a, int b) {
    return dist[a] + dist[b] - 2ll * dist[query(a, b)];
  }
};
LCA lca;
vector<int> sources;
bool visited[maxN];
vector<int> vis;
void bfs1(int uu, int ex) {
  queue<int> q;
  q.push(uu);
  visited[uu] = true;
  vis.emplace_back(uu);
  if (mark[uu]) sources.emplace_back(uu);
  D[uu] = INF;
  while (!q.empty()) {
    int u = q.front(); q.pop();
    for (auto [v, w] : adj[u]) {
      if (v == ex) continue;
      if  (!visited[v]) {
        if (mark[v]) sources.emplace_back(v);
        q.push(v);
        visited[v] = true;
        D[v] = INF;
        vis.emplace_back(v);
      }
    }
  }
  for (int x : vis) visited[x] = false;
  vis.clear();
}
void bfs(int exclude) {
  queue<int> q;
  for (int u : sources) {
    D[u] = 0;
    q.push(u);
  }
  sources.clear();
  while (!q.empty()) {
    int u = q.front(); q.pop();
    for (auto [v, w] : adj[u]) {
      if (v == exclude) continue;
      if (D[v] > D[u] + w) {
        D[v] = D[u] + w;
        q.push(v);
      }
    }
  }
}
namespace IO {
    const int BUFSIZE = 1<<14;
    char buf[BUFSIZE + 1], *inp = buf;
    bool reacheof;
    char get_char() {
        if (!*inp && !reacheof) {
            memset(buf, 0, sizeof buf);
            int tmp = fread(buf, 1, BUFSIZE, stdin);
            if (tmp != BUFSIZE) reacheof = true;
            inp = buf;
        }
        return *inp++;
    }
    template<typename T>
    T get() {
        int neg = 0;
        T res = 0;
        char c = get_char();
        while (!(c >= '0' && c <= '9') && c != '-' && c != '+') c = get_char();
        if (c == '+') { neg = 0; }
        else if (c == '-') { neg = 1; }
        else res = c - '0';
        c = get_char();
        while (c >= '0' && c <= '9') {
            res = res * 10 + (c - '0');
            c = get_char();
        }
        return neg ? -res : res;
    }
};
int read() {
    return IO::get<int>();
}
void write(ll xo) {
    if (xo > 9)
        write(xo / 10);
    putchar(xo % 10 + '0');
}
signed main() {
  #define TASK "VALLET"
    if (fopen(TASK ".inp", "r")) {
      freopen(TASK ".inp", "r", stdin);
      freopen(TASK ".out", "w", stdout);
    }
  ios::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  cin >> n >> m >> q >> H;
  --H;
  vector<tuple<int, int, int>> edges;
  for (int i = 1; i < n; ++i) {
    int u, v, w;
    cin >> u >> v >> w;
    --u;
    --v;
    edges.emplace_back(u, v, w);
    adj[u].emplace_back(v, w);
    adj[v].emplace_back(u, w);
  }
  for (int i = 1; i <= m; ++i) {
    cin >> C[i];
    --C[i];
    mark[C[i]] = true; 
  }
  for (int i = 0; i < n; ++i) {
    in[i] = out[i] = -1;
  }
  lca = LCA(n);
  lca.build(H);
  int idx = 0;
  vector<tuple<int, int, int>> heavy;
  int BLOCKS = sqrt(n);
  while (q--) {
    int I, R;
    cin >> I >> R;
    --I;
    --R;
    auto [u, v, w] = edges[I];
    if (depth[u] < depth[v]) swap(u, v);
    if (lca.in_subtree(u, R)) {
      if (cnt[u] <= BLOCKS) {
        bfs1(u, v);
        bfs(v);
        res[++idx] = D[R];
      } else {
        heavy.emplace_back(u, R, ++idx);
      }
    } else res[++idx] = -1;
  }
  for (auto [u, R, pos] : heavy) {
    res[pos] = INF;
    for (int i = 1; i <= m; ++i) {
      if (lca.in_subtree(u, C[i])) {
        res[pos] = min(res[pos], lca.get_dist(R, C[i]));
      }
    }
  }
  for (int i = 1; i <= idx; ++i) {
    if (res[i] == -1) cout << "escaped\n";
    else if (res[i] == INF) cout << "oo\n";
    else cout << res[i] << '\n';
  }
  return 0;
}
Compilation message (stderr)
valley.cpp: In function 'int main()':
valley.cpp:214:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  214 |       freopen(TASK ".inp", "r", stdin);
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:215:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  215 |       freopen(TASK ".out", "w", stdout);
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |