This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
/*
    ghmt the cutie :3
          UwU
*/
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 1e18
#define f first
#define s second
#define pii pair<int, int>
#define vi vector<int>
const int MOD = 1'000'000'000 + 7;
void setIO(string name = "")
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
#ifdef LOCAL
    freopen("inp.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#else
    if (!name.empty())
    {
        freopen((name + ".INP").c_str(), "r", stdin);
        freopen((name + ".OUT").c_str(), "w", stdout);
    }
#endif
}
const int MAXN = 1e5;
int n, s, q, e;
vector<pii> g[MAXN + 5];
vector<array<int, 3>> edges;
vi shops;
vector<pii> queries;
namespace sub12 {
bool check() {
    if(n <= 100 && q <= 10'000) return true;
    return n <= 1000 && q <= 1000;
}
int st[MAXN + 5], en[MAXN + 5];
int timeDfs = 0;
int f[MAXN + 5], h[MAXN + 5];
int up[MAXN + 5][20];
void pre_dfs(int u, int par) {
    st[u] = ++timeDfs;
    up[u][0] = par;
    for(int i = 1; i < 20; i++) {
        up[u][i] = up[up[u][i - 1]][i - 1];
    }
    for(auto [v, w] : g[u]) {
        if(v == par) continue;
        f[v] = f[u] + w;
        h[v] = h[u] + 1;
        pre_dfs(v, u);
    }
    en[u] = ++timeDfs;
}
int LCA(int u, int v) {
    if(h[u] != h[v]) {
        if(h[u] < h[v]) swap(u, v);
        for(int i = 19; i >= 0; i--) {
            if(h[u] - h[v] >= (1 << i)) u = up[u][i];
        }
    }
    
    if(u == v) return u;
    for(int i = 19; i >= 0; i--) {
        if(up[u][i] != up[v][i]) u = up[u][i], v = up[v][i];
    }
    
    return up[u][0];
}
bool is_ancestor(int u, int v) {
    return st[u] <= st[v] && en[v] <= en[u];
}
void solve() {
    pre_dfs(e, e);
    for(auto &[u, v, w] : edges) {
        if(h[u] < h[v]) swap(u, v);
    }
    for(auto [id, r] : queries) {
        id--;
        if(!is_ancestor(edges[id][0], r)) {
            cout << "escaped\n";
            continue;
        }
        int res = INF;
        for(int d : shops) {
            if(!is_ancestor(edges[id][0], d)) continue;
            int p = LCA(d, r);
            res = min(res, f[d] + f[r] - 2 * f[p]);
        }
        if(res != INF) {
            cout << res << '\n';
            continue;
        }
        cout << "oo\n";
    }
}
}; 
namespace sub3 {
bool check() {
    if(n <= 100'000 && q <= 100'000 && s == n) return true;
    return false;
}
int h[MAXN + 5];
int st[MAXN + 5], en[MAXN + 5];
int timeDfs = 0;
void pre_dfs(int u, int par) {
    st[u] = ++timeDfs;
    for(auto [v,w] : g[u]) {
        if(v == par) continue;
        h[v] = h[u] + 1;
        pre_dfs(v, u);
    }
    en[u] = ++timeDfs;
}
void solve() {
    pre_dfs(e, e);
     
    for(auto &[u, v, w] : edges) {
        if(h[u] < h[v]) swap(u, v);
    }
    for(auto [id, r] : queries) {
        id--;
        int u = edges[id][0], v = r;
        // cout << u << ' ' << v << '\n';
        if(st[u] <= st[v] && en[v] <= en[u]) cout << "0\n";
        else cout << "escaped" << '\n';
    }
}
}
namespace sub4 {
bool check() {
    return n <= 100'000 && q <= 100'000;
}
int h[MAXN + 5];
int st[MAXN + 5], en[MAXN + 5];
int timeDfs = 0;
bool is_shop[MAXN + 5];
int f[MAXN + 5];
int d[MAXN + 5];
int val[MAXN + 5];
// f[i] = min distance from root to shop in subtree i
// d[i] = distance from root to i
// val[i] -
void pre_dfs(int u = e, int par = e) {
    st[u] = ++timeDfs;
    f[u] = (is_shop[u] ? d[u] : INF);
    for(auto [v, w] : g[u]) {
        if(v == par) continue;
        h[v] = h[u] + 1;
        d[v] = d[u] + w;
        pre_dfs(v, u);
        f[u] = min(f[u], f[v]); 
    }
    val[u] = f[u] - 2 * d[u];
    en[u] = ++timeDfs;
}
int up[MAXN + 5][20];
int mi[MAXN + 5][20];
void upmi_dfs(int u = e, int par = e) {
    up[u][0] = par, mi[u][0] = val[u];
    for(int i = 1; i < 20; i++) {
        up[u][i] = up[up[u][i - 1]][i - 1];
        mi[u][i] = min(mi[u][i - 1], mi[up[u][i - 1]][i - 1]);
    }
    
    for(auto [v, w] : g[u]) {
        if(v == par) continue;
        upmi_dfs(v, u);
    }
}
bool is_ancestor(int u, int v) {
    return st[u] <= st[v] && en[v] <= en[u];
}
int mi_val(int root, int node) {
    int res = INF;
    for(int i = 19; i >= 0; i--) {
        if(is_ancestor(root, up[node][i])) {
            res = min(res, mi[node][i]);
            node = up[node][i];
        }
    }
    return min(res, val[node]);
}
void solve() {    
    for(int x : shops) is_shop[x] = 1;
    d[e] = 0;
    pre_dfs();
    upmi_dfs();
    // for(int i = 1; i <= n; i++) cout << d[i] << ' '; cout << '\n'; 
    // for(int i = 1; i <= n; i++) cout << f[i] << ' '; cout << '\n';
    // 
    for(auto &[u, v, w] : edges) {
        if(h[u] < h[v]) swap(u, v);
    }
    for(auto [id, r] : queries) {
        id--;
        if(!is_ancestor(edges[id][0], r)) {
            cout << "escaped\n";
            continue;
        }
        
        // cout << edges[id][0] << '\n'; 
        if(f[edges[id][0]] == INF) {
            cout << "oo\n";
            continue;
        }
        
        cout << mi_val(edges[id][0], r) + d[r] << '\n';
    }
}
}
void solve()
{
    cin >> n >> s >> q >> e;
    for(int i = 1; i < n; i++) {
        int u, v, w; cin >> u >> v >> w;
        g[u].push_back({v, w});
        g[v].push_back({u, w});
        edges.push_back({u, v, w}); 
    }
    shops.resize(s);
    for(int &i : shops) cin >> i;
    queries.resize(q);
    for(auto &it : queries) cin >> it.f >> it.s;
    if(sub12::check()) {
        sub12::solve();
        return;
    }
    if(sub3::check()) {
        sub3::solve();
        return;
    }
    if(sub4::check()) {
        sub4::solve();
        return;
    }
}
signed main()
{
    setIO();
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
}
Compilation message (stderr)
valley.cpp: In function 'void setIO(std::string)':
valley.cpp:28:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   28 |         freopen((name + ".INP").c_str(), "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:29:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   29 |         freopen((name + ".OUT").c_str(), "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... |