This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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;
void dfs(int u, int par, int ex) {
  if (mark[u]) sources.emplace_back(u);
  D[u] = INF;
  for (auto [v, w] : adj[u]) {
    if (v == par || v == ex) continue;
    dfs(v, u, ex);
  }
}
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);
      }
    }
  }
}
static struct FastInput {
  static constexpr int BUF_SIZE = 1 << 20;
  char buf[BUF_SIZE];
  size_t chars_read = 0;
  size_t buf_pos = 0;
  FILE *in = stdin;
  char cur = 0;
  inline char get_char() {
    if (buf_pos >= chars_read) {
      chars_read = fread(buf, 1, BUF_SIZE, in);
      buf_pos = 0;
      buf[0] = (chars_read == 0 ? -1 : buf[0]);
    }
    return cur = buf[buf_pos++];
  }
  inline void tie(int) {}
  inline explicit operator bool() {
    return cur != -1;
  }
  inline static bool is_blank(char c) {
    return c <= ' ';
  }
  inline bool skip_blanks() {
    while (is_blank(cur) && cur != -1) {
      get_char();
    }
    return cur != -1;
  }
  inline FastInput& operator>>(char& c) {
    skip_blanks();
    c = cur;
    return *this;
  }
  inline FastInput& operator>>(string& s) {
    if (skip_blanks()) {
      s.clear();
      do {
        s += cur;
      } while (!is_blank(get_char()));
    }
    return *this;
  }
  template <typename T>
  inline FastInput& read_integer(T& n) {
    n = 0;
    if (skip_blanks()) {
      int sign = +1;
      if (cur == '-') {
        sign = -1;
        get_char();
      }
      do {
        n += n + (n << 3) + cur - '0';
      } while (!is_blank(get_char()));
      n *= sign;
    }
    return *this;
  }
  template <typename T>
  inline typename enable_if<is_integral<T>::value, FastInput&>::type operator>>(T& n) {
    return read_integer(n);
  }
  #if !defined(_WIN32) || defined(_WIN64)
  inline FastInput& operator>>(__int128& n) {
    return read_integer(n);
  }
  #endif
  template <typename T>
  inline typename enable_if<is_floating_point<T>::value, FastInput&>::type operator>>(T& n) {
    n = 0;
    if (skip_blanks()) {
      string s;
      (*this) >> s;
      sscanf(s.c_str(), "%lf", &n);
    }
    return *this;
  }
} fast_input;
#define cin fast_input
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) {
        dfs(u, -1, 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:235:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  235 |       freopen(TASK ".inp", "r", stdin);
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:236:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  236 |       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... |