Problem:
鉄道路線
ある国の鉄道網に、自動改札を導入することになりました。導入にあたって難しい問題の一つは、与えられた切符で、指定された駅の間を移動できるかどうかを判定することです。それぞれの切符には乗車駅と降車駅が記載されています。この切符でできるのは、「乗車駅で乗って、降車駅で降りる」ことだけではなく、途中乗車や途中下車も許されています。
この鉄道網にはS 個の駅があり、そのうちR 組の駅は隣り合っていて、他の駅を経由せずに双方向に鉄道で移動することができます。隣り合った駅を結ぶ線路はひとつしかありません。隣り合った駅の間の距離は、この線路に沿って測った距離です。ある駅からある駅までの経路は鉄道網の形状によっては複数通り考えられますが、そのうち最も距離が短くなるような経路を最短経路と呼ぶことにします。そのような経路が複数ある場合、どちらも最短経路として認められます。
乗車駅 a、降車駅 b の切符で駅 c から駅 d まで移動できるのは、以下の条件をすべて満たす経路 p が存在するときです。
経路 p は、駅 a から駅 b への最短経路である。
経路 p は、駅 a から出発し、駅 c、駅 d の順に経由し、駅 b で終わる経路である。また、駅 c から駅 d の区間はこの2 駅の最短経路になっている。
路線図と切符の情報が与えられます。次に、始点と終点の組がいくつか与えられるので、その切符で始点から終点へ移動できるかどうかを判定するプログラムを作成してください。
入力
入力は１つのデータセットからなる。入力データは以下の形式で与えられる。
S R
u
1
v
1
w
1
u
2
v
2
w
2
:
u
R
v
R
w
R
a b Q
c
1
d
1
:
c
Q
d
Q
各行で与えられる数値は１つの空白で区切られている。
１行目は２つの整数からなる。S (2 ≤ S ≤ 100000) は鉄道路線図に現れる駅の数、R (1 ≤ R ≤ 200000) は隣り合った駅の組の数である。続く R 行に、隣り合った駅の間を直接つなぐ線路の情報が与えられる。u
i
と v
i
(1 ≤ u
i
, v
i
≤ S) は i 番目の線路の両端の駅の番号を示す。w
i
(1 ≤ w
i
≤ 1000) はこれらの駅の間の距離を表す整数である。ただし、各駅には 1 から S までの番号が重複なく割り振られており、u
i
≠ v
i
とする。
続く１行は３つの整数からなる。最初の２つの整数は切符の区間を表し、a は乗車駅、b は降車駅 (1 ≤ a, b ≤ S) である。３つ目の整数 Q (1 ≤ Q ≤ 40000) は質問の数を示す。続く Q 行に質問が与えられる。 c
i
とd
i
(1 ≤ c
i
, d
i
≤ S)は i 番目の質問の乗車駅と降車駅を示す。ただし、a ≠ b、c
i
≠ d
i
とする。
出力
質問ごとに、与えられた切符で移動できるなら Yes を、できないなら No を１行に出力する。
入力例
6 7
1 2 3
1 4 1
2 3 5
4 3 1
3 6 2
4 5 2
5 6 1
1 6 6
1 6
4 3
4 6
5 6
2 6
2 5
出力例
Yes
Yes
Yes
Yes
No
No

Submitted solutions:

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            ll nxt = g[i][j].first;
            ll cost = g[i][j].second;
            if (d[i] == inf || d[nxt] == inf)
            {
                continue;
            }
            if (drev[i] == inf || drev[nxt] == inf)
            {
                continue;
            }
            if (d[i] + cost + drev[nxt] == d[B])
            {
                g_short[i].push_back(nxt);
            }
        }
    }
    vector<vector<ll>> G;
    vector<ll> ar;
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<ull> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ll WS = 64;
    ll N = G.size();
    for (ll i = 0; i < Q; i += WS)
    {
        vector<ull> C(N);
        rep(j, 0, WS)
        {
            if (i + j >= Q)
            {
                continue;
            }
            C[queries[i + j].first] |= (1ULL << (ull)j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i + j >= Q)
            {
                continue;
            }
            F[i + j] = (C[queries[i + j].second] >> (ull)j) & (1ULL);
        }
    }
    rep(i, 0, Q)
    {
        if (F[i] == 1)
        {
            cout << "Yes" << endl;
        }
        else
        {
            cout << "No" << endl;
        }
    }
}
accuracy: 1
time_ms: 260
memory_kb: 71232
final_rank: 7

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            if (d[i] + g[i][j].second + drev[g[i][j].first] == d[B])
            {
                g_short[i].push_back(g[i][j].first);
            }
        }
    }
    vector<vector<ll>> G;
    vector<ll> ar;
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<ull> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ll WS = 64;
    ll N = G.size();
    for (ll i = 0; i < Q; i += WS)
    {
        vector<ull> C(N);
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            C[queries[i * WS + j].first] |= (1ULL << (ull)j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            F[i * WS + j] = (C[queries[i * WS + j].second] >> (ull)j) & (1ULL);
        }
    }
    rep(i, 0, Q)
    {
        if (F[i] == 1)
        {
            cout << "Yes"<<Endl;
        }
        else
        {
            cout << "No"<<endl;
        }
    }
}
accuracy: 0.6666666666666666
time_ms: 70
memory_kb: 28784
final_rank: 17

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            if (d[i] + g[i][j].second + drev[g[i][j].first] == d[B])
            {
                g_short[i].push_back(g[i][j].first);
            }
        }
    }
    vector<vector<ll>> G;
    vector<ll> ar;
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<ull> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ll WS = 60;
    ll N = G.size();
    for (ll i = 0; i < Q; i += WS)
    {
        vector<ull> C(N);
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            C[queries[i * WS + j].first] |= (1ULL << (ull)j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            F[i * WS + j] = (C[queries[i * WS + j].second] >> (ull)j) & (1ULL);
        }
    }
    rep(i, 0, Q)
    {
        jge(F[i]==1, "Yes", "No");
    }
}
accuracy: 0.6666666666666666
time_ms: 50
memory_kb: 29092
final_rank: 14

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            if (d[i] + g[i][j].second + drev[g[i][j].first] == d[B])
            {
                g_short[i].push_back(g[i][j].first);
            }
        }
    }
    vector<vector<ll>> G;
    vector<ll> ar;
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<ull> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ll WS = 64;
    ll N = G.size();
    for (ll i = 0; i < Q; i += WS)
    {
        vector<ull> C(N);
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            C[queries[i * WS + j].first] |= (1ULL << (ull)j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            F[i * WS + j] = (C[queries[i * WS + j].second] >> (ull)j) & (1ULL);
        }
    }
    rep(i, 0, Q)
    {
        jge(F[i]==1, "Yes", "No");
    }
}
accuracy: 0.6666666666666666
time_ms: 50
memory_kb: 29088
final_rank: 13

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            if (d[i] + g[i][j].second + drev[g[i][j].first] == d[B])
            {
                g_short[i].push_back(g[i][j].first);
            }
        }
    }
    vector<vector<ll>> G;
    vector<ll> ar;
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<ull> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ull WS = 64;
    ull N = G.size();
    for (ull i = 0; i < Q; i += WS)
    {
        vector<ull> C(N);
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            C[queries[i * WS + j].first] |= (1ULL << j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            F[i * WS + j] = (C[queries[i * WS + j].second] >> j) & (1ULL);
        }
    }
    rep(i, 0, Q)
    {
        jge(F[i]==1, "Yes", "No");
    }
}
accuracy: 0.6666666666666666
time_ms: 50
memory_kb: 29092
final_rank: 14

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            if (d[i] + g[i][j].second + drev[g[i][j].first] == d[B])
            {
                g_short[i].push_back(g[i][j].first);
            }
        }
    }
    vector<vector<ll>> G;
    vector<ll> ar;
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<ll> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ll WS = 64;
    ll N = G.size();
    for (ll i = 0; i < Q; i += WS)
    {
        vector<ull> C(N);
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            C[queries[i * WS + j].first] |= (1ULL << j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            F[i * WS + j] = (C[queries[i * WS + j].second] >> j) & (1ULL);
        }
    }
    rep(i, 0, Q)
    {
        jge(F[i]==1, "Yes", "No");
    }
}
accuracy: 0.6666666666666666
time_ms: 50
memory_kb: 29092
final_rank: 14

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            if (d[i] + g[i][j].second + drev[g[i][j].first] == d[B])
            {
                g_short[i].push_back(g[i][j].first);
            }
        }
    }
    vector<vector<ll>> G;
    vector<ll> ar;
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<bool> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ll WS = 64;
    ll N = G.size();
    for (ll i = 0; i < Q; i += WS)
    {
        vector<ll> C(N);
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            C[queries[i * WS + j].first] += (1LL << j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            F[i * WS + j] = (C[queries[i * WS + j].second] >> j) & 1;
        }
    }
    rep(i, 0, Q)
    {
        jge(F[i], "Yes", "No");
    }
}
accuracy: 0.6666666666666666
time_ms: 40
memory_kb: 29088
final_rank: 12

code_snippet: #include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i, m, n) for (ll i = (ll)m; i < (ll)n; i++)
#define drep(i, m, n) for (ll i = m - 1; i >= n; i--)
#define Endl endl
#define all(a) a.begin(), a.end()
#define pr(i, j) make_pair(i, j)
#define isin(x, l, r) (l <= x && x < r)
#define chmin(a, b) a = min(a, b)
#define chmax(a, b) a = max(a, b)
#define srt(ar) sort(ar.begin(), ar.end())
#define rev(ar) reverse(ar.begin(), ar.end())
#define jge(f, s, t) cout << (f ? s : t) << endl
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#define printar(ar)             \
    do                          \
    {                           \
        for (auto dbg : ar)     \
        {                       \
            cout << dbg << " "; \
        }                       \
        cout << endl;           \
    } while (0)
const ll inf = 1e18;
const ld pi = 3.14159265358979;
const ld eps = 1e-9;
template <class T, ll n, ll idx = 0>
auto make_vec(const ll (&d)[n], const T &init) noexcept
{
    if constexpr (idx < n)
        return std::vector(d[idx], make_vec<T, n, idx + 1>(d, init));
    else
        return init;
}

template <class T, ll n>
auto make_vec(const ll (&d)[n]) noexcept
{
    return make_vec(d, T{});
}
//////////////// 以下を貼る ////////////////
template <class T>
size_t HashCombine(const size_t seed, const T &v)
{
    return seed ^ (std::hash<T>()(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2));
}
/* pair用 */
template <class T, class S>
struct std::hash<std::pair<T, S>>
{
    size_t operator()(const std::pair<T, S> &keyval) const noexcept
    {
        return HashCombine(std::hash<T>()(keyval.first), keyval.second);
    }
};
// グラフを与えると[集約後のグラフh]と[元の頂点iがhにおける頂点ar[i]になるようなar]のpairを返す
pair<vector<vector<ll>>, vector<ll>> scc(vector<vector<ll>> in)
{
    static vector<vector<ll>> g = in;
    static ll n = g.size();
    static vector<vector<ll>> g_rev(n);
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            g_rev[g[i][j]].push_back(i);
        }
    }
    static vector<bool> F(n, false);
    static vector<ll> T(n);
    static ll cnt = 0;
    static vector<bool> G(n);
    static vector<ll> ar(n);
    static ll v = 0;
    struct
    {
        void dfs(ll now)
        {
            F[now] = true;
            rep(i, 0, g[now].size())
            {
                ll nxt = g[now][i];
                if (!F[nxt])
                {
                    dfs(nxt);
                }
            }
            T[n - 1 - cnt] = now;
            cnt++;
        }
        void dfs2(ll now)
        {
            G[now] = true;
            ar[now] = v;
            rep(i, 0, g_rev[now].size())
            {
                ll nxt = g_rev[now][i];
                if (!G[nxt])
                {
                    dfs2(nxt);
                }
            }
        }
    } I;
    rep(i, 0, n)
    {
        if (!F[i])
        {
            I.dfs(i);
        }
    }
    rep(i, 0, n)
    {
        if (!G[T[i]])
        {
            I.dfs2(T[i]);
            v++;
        }
    }
    vector<vector<ll>> h(v);
    unordered_map<pair<ll, ll>, bool> mp;
    rep(i, 0, n)
    {
        rep(j, 0, g[i].size())
        {
            ll A = ar[i];
            ll B = ar[g[i][j]];
            if (A != B && !mp[pr(A, B)])
            {
                mp[pr(A, B)] = true;
                h[A].push_back(B);
            }
        }
    }
    return pr(h, ar);
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    ll s, r;
    cin >> s >> r;
    vector<vector<pair<ll, ll>>> g(s);
    rep(i, 0, r)
    {
        ll u, v, w;
        cin >> u >> v >> w;
        u--;
        v--;
        g[u].push_back(pr(v, w));
        g[v].push_back(pr(u, w));
    }
    ll A, B, Q;
    cin >> A >> B >> Q;
    A--;
    B--;
    vector<vector<ll>> g_short(s); // 最短経路グラフ
    vector<ll> d(s, inf), drev(s, inf);
    priority_queue<pair<ll, ll>, vector<pair<ll, ll>>, greater<pair<ll, ll>>> que;
    que.emplace(pr(0, A));
    d[A] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != d[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (d[nxt] > D + cost)
            {
                d[nxt] = d[now] + cost;
                que.emplace(pr(d[nxt], nxt));
            }
        }
    }
    que.emplace(pr(0, B));
    drev[B] = 0;
    while (!que.empty())
    {
        ll now, D;
        tie(D, now) = que.top();
        que.pop();
        if (D != drev[now])
        {
            continue;
        }
        rep(i, 0, g[now].size())
        {
            ll nxt = g[now][i].first;
            ll cost = g[now][i].second;
            if (drev[nxt] > D + cost)
            {
                drev[nxt] = D + cost;
                que.emplace(pr(drev[nxt], nxt));
            }
        }
    }
    rep(i, 0, s)
    {
        rep(j, 0, g[i].size())
        {
            if (d[i] + g[i][j].second + drev[g[i][j].first] == d[B])
            {
                g_short[i].push_back(g[i][j].first);
            }
        }
    }
    vector<vector<ll>> G(s);
    vector<ll> ar(s);
    tie(G, ar) = scc(g_short);
    vector<pair<ll, ll>> queries;
    vector<bool> F(Q);
    rep(i, 0, Q)
    {
        ll c, d;
        cin >> c >> d;
        c--;
        d--;
        queries.push_back(pr(ar[c], ar[d]));
    }
    ll WS = 64;
    ll N = G.size();
    for (ll i = 0; i < Q; i += WS)
    {
        vector<ll> C(N);
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            C[queries[i * WS + j].first] += (1LL << j);
        }
        rep(j, 0, N)
        {
            rep(k, 0, G[j].size())
            {
                ll nxt = G[j][k];
                C[nxt] |= C[j];
            }
        }
        rep(j, 0, WS)
        {
            if (i * WS + j >= Q)
            {
                continue;
            }
            F[i * WS + j] = (C[queries[i * WS + j].second] >> j) & 1;
        }
    }
    rep(i, 0, Q)
    {
        jge(F[i], "Yes", "No");
    }
}
accuracy: 0.6666666666666666
time_ms: 50
memory_kb: 31908
final_rank: 18

code_snippet: #line 1 "main.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0275"
#line 1 "library/my_template.hpp"
#if defined(LOCAL)
#include <my_template_compiled.hpp>
#else
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;

template <class T>
constexpr T infty = 0;
template <>
constexpr int infty<int> = 1'000'000'000;
template <>
constexpr ll infty<ll> = ll(infty<int>) * infty<int> * 2;
template <>
constexpr u32 infty<u32> = infty<int>;
template <>
constexpr u64 infty<u64> = infty<ll>;
template <>
constexpr i128 infty<i128> = i128(infty<ll>) * infty<ll>;
template <>
constexpr double infty<double> = infty<ll>;
template <>
constexpr long double infty<long double> = infty<ll>;

using pi = pair<ll, ll>;
using vi = vector<ll>;
template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

// https://trap.jp/post/1224/
#define FOR1(a) for (ll _ = 0; _ < ll(a); ++_)
#define FOR2(i, a) for (ll i = 0; i < ll(a); ++i)
#define FOR3(i, a, b) for (ll i = a; i < ll(b); ++i)
#define FOR4(i, a, b, c) for (ll i = a; i < ll(b); i += (c))
#define FOR1_R(a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR2_R(i, a) for (ll i = (a)-1; i >= ll(0); --i)
#define FOR3_R(i, a, b) for (ll i = (b)-1; i >= ll(a); --i)
#define overload4(a, b, c, d, e, ...) e
#define overload3(a, b, c, d, ...) d
#define FOR(...) overload4(__VA_ARGS__, FOR4, FOR3, FOR2, FOR1)(__VA_ARGS__)
#define FOR_R(...) overload3(__VA_ARGS__, FOR3_R, FOR2_R, FOR1_R)(__VA_ARGS__)

#define FOR_subset(t, s) \
  for (ll t = (s); t >= 0; t = (t == 0 ? -1 : (t - 1) & (s)))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T, typename U>
T ceil(T x, U y) {
  return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U>
T floor(T x, U y) {
  return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

template <typename T, typename U>
T SUM(const vector<U> &A) {
  T sum = 0;
  for (auto &&a: A) sum += a;
  return sum;
}

#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) \
  sort(all(x)), x.erase(unique(all(x)), x.end()), x.shrink_to_fit()

template <typename T>
T POP(deque<T> &que) {
  T a = que.front();
  que.pop_front();
  return a;
}
template <typename T>
T POP(pq<T> &que) {
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(pqg<T> &que) {
  assert(!que.empty());
  T a = que.top();
  que.pop();
  return a;
}
template <typename T>
T POP(vc<T> &que) {
  assert(!que.empty());
  T a = que.back();
  que.pop_back();
  return a;
}

template <typename F>
ll binary_search(F check, ll ok, ll ng, bool check_ok = true) {
  if (check_ok) assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
  }
  return ok;
}
template <typename F>
double binary_search_real(F check, double ok, double ng, int iter = 100) {
  FOR(iter) {
    double x = (ok + ng) / 2;
    tie(ok, ng) = (check(x) ? mp(x, ng) : mp(ok, x));
  }
  return (ok + ng) / 2;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

// ? は -1
vc<int> s_to_vi(const string &S, char first_char) {
  vc<int> A(S.size());
  FOR(i, S.size()) { A[i] = (S[i] != '?' ? S[i] - first_char : -1); }
  return A;
}

template <typename T, typename U>
vector<T> cumsum(vector<U> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

// stable sort
template <typename T>
vector<int> argsort(const vector<T> &A) {
  vector<int> ids(len(A));
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return (A[i] == A[j] ? i < j : A[i] < A[j]); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  vc<T> B(len(I));
  FOR(i, len(I)) B[i] = A[I[i]];
  return B;
}
#endif
#line 1 "library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>

namespace fastio {
#define FASTIO
// クラスが read(), print() を持っているかを判定するメタ関数
struct has_write_impl {
  template <class T>
  static auto check(T &&x) -> decltype(x.write(), std::true_type{});

  template <class T>
  static auto check(...) -> std::false_type;
};

template <class T>
class has_write : public decltype(has_write_impl::check<T>(std::declval<T>())) {
};

struct has_read_impl {
  template <class T>
  static auto check(T &&x) -> decltype(x.read(), std::true_type{});

  template <class T>
  static auto check(...) -> std::false_type;
};

template <class T>
class has_read : public decltype(has_read_impl::check<T>(std::declval<T>())) {};

struct Scanner {
  FILE *fp;
  char line[(1 << 15) + 1];
  size_t st = 0, ed = 0;
  void reread() {
    memmove(line, line + st, ed - st);
    ed -= st;
    st = 0;
    ed += fread(line + ed, 1, (1 << 15) - ed, fp);
    line[ed] = '\0';
  }
  bool succ() {
    while (true) {
      if (st == ed) {
        reread();
        if (st == ed) return false;
      }
      while (st != ed && isspace(line[st])) st++;
      if (st != ed) break;
    }
    if (ed - st <= 50) {
      bool sep = false;
      for (size_t i = st; i < ed; i++) {
        if (isspace(line[i])) {
          sep = true;
          break;
        }
      }
      if (!sep) reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    while (true) {
      size_t sz = 0;
      while (st + sz < ed && !isspace(line[st + sz])) sz++;
      ref.append(line + st, sz);
      st += sz;
      if (!sz || st != ed) break;
      reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    bool neg = false;
    if (line[st] == '-') {
      neg = true;
      st++;
    }
    ref = T(0);
    while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
    if (neg) ref = -ref;
    return true;
  }
  template <typename T,
            typename enable_if<has_read<T>::value>::type * = nullptr>
  inline bool read_single(T &x) {
    x.read();
    return true;
  }
  bool read_single(double &ref) {
    string s;
    if (!read_single(s)) return false;
    ref = std::stod(s);
    return true;
  }
  bool read_single(char &ref) {
    string s;
    if (!read_single(s) || s.size() != 1) return false;
    ref = s[0];
    return true;
  }
  template <class T>
  bool read_single(vector<T> &ref) {
    for (auto &d: ref) {
      if (!read_single(d)) return false;
    }
    return true;
  }
  template <class T, class U>
  bool read_single(pair<T, U> &p) {
    return (read_single(p.first) && read_single(p.second));
  }
  template <size_t N = 0, typename T>
  void read_single_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
      auto &x = std::get<N>(t);
      read_single(x);
      read_single_tuple<N + 1>(t);
    }
  }
  template <class... T>
  bool read_single(tuple<T...> &tpl) {
    read_single_tuple(tpl);
    return true;
  }
  void read() {}
  template <class H, class... T>
  void read(H &h, T &... t) {
    bool f = read_single(h);
    assert(f);
    read(t...);
  }
  Scanner(FILE *fp) : fp(fp) {}
};

struct Printer {
  Printer(FILE *_fp) : fp(_fp) {}
  ~Printer() { flush(); }

  static constexpr size_t SIZE = 1 << 15;
  FILE *fp;
  char line[SIZE], small[50];
  size_t pos = 0;
  void flush() {
    fwrite(line, 1, pos, fp);
    pos = 0;
  }
  void write(const char val) {
    if (pos == SIZE) flush();
    line[pos++] = val;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  void write(T val) {
    if (pos > (1 << 15) - 50) flush();
    if (val == 0) {
      write('0');
      return;
    }
    if (val < 0) {
      write('-');
      val = -val; // todo min
    }
    size_t len = 0;
    while (val) {
      small[len++] = char(0x30 | (val % 10));
      val /= 10;
    }
    for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
    pos += len;
  }
  void write(const string s) {
    for (char c: s) write(c);
  }
  void write(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) write(s[i]);
  }
  void write(const double x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  void write(const long double x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  template <typename T,
            typename enable_if<has_write<T>::value>::type * = nullptr>
  inline void write(T x) {
    x.write();
  }
  template <class T>
  void write(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  template <class T, class U>
  void write(const pair<T, U> val) {
    write(val.first);
    write(' ');
    write(val.second);
  }
  template <size_t N = 0, typename T>
  void write_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
      if constexpr (N > 0) { write(' '); }
      const auto x = std::get<N>(t);
      write(x);
      write_tuple<N + 1>(t);
    }
  }
  template <class... T>
  bool write(tuple<T...> tpl) {
    write_tuple(tpl);
    return true;
  }
  template <class T, size_t S>
  void write(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  void write(i128 val) {
    string s;
    bool negative = 0;
    if (val < 0) {
      negative = 1;
      val = -val;
    }
    while (val) {
      s += '0' + int(val % 10);
      val /= 10;
    }
    if (negative) s += "-";
    reverse(all(s));
    if (len(s) == 0) s = "0";
    write(s);
  }
};
Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);
void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  printer.write(head);
  if (sizeof...(Tail)) printer.write(' ');
  print(forward<Tail>(tail)...);
}

void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
  scanner.read(head);
  read(tail...);
}
} // namespace fastio
using fastio::print;
using fastio::flush;
using fastio::read;

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)   \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 2 "library/graph/base.hpp"

template <typename T>
struct Edge {
  int frm, to;
  T cost;
  int id;
};

template <typename T = int, bool directed = false>
struct Graph {
  int N, M;
  using cost_type = T;
  using edge_type = Edge<T>;
  vector<edge_type> edges;
  vector<int> indptr;
  vector<edge_type> csr_edges;
  vc<int> vc_deg, vc_indeg, vc_outdeg;
  bool prepared;

  class OutgoingEdges {
  public:
    OutgoingEdges(const Graph* G, int l, int r) : G(G), l(l), r(r) {}

    const edge_type* begin() const {
      if (l == r) { return 0; }
      return &G->csr_edges[l];
    }

    const edge_type* end() const {
      if (l == r) { return 0; }
      return &G->csr_edges[r];
    }

  private:
    const Graph* G;
    int l, r;
  };

  bool is_prepared() { return prepared; }
  constexpr bool is_directed() { return directed; }

  Graph() : N(0), M(0), prepared(0) {}
  Graph(int N) : N(N), M(0), prepared(0) {}

  void build(int n) {
    N = n, M = 0;
    prepared = 0;
    edges.clear();
    indptr.clear();
    csr_edges.clear();
    vc_deg.clear();
    vc_indeg.clear();
    vc_outdeg.clear();
  }

  void add(int frm, int to, T cost = 1, int i = -1) {
    assert(!prepared);
    assert(0 <= frm && 0 <= to && to < N);
    if (i == -1) i = M;
    auto e = edge_type({frm, to, cost, i});
    edges.eb(e);
    ++M;
  }

  // wt, off
  void read_tree(bool wt = false, int off = 1) { read_graph(N - 1, wt, off); }

  void read_graph(int M, bool wt = false, int off = 1) {
    for (int m = 0; m < M; ++m) {
      INT(a, b);
      a -= off, b -= off;
      if (!wt) {
        add(a, b);
      } else {
        T c;
        read(c);
        add(a, b, c);
      }
    }
    build();
  }

  void build() {
    assert(!prepared);
    prepared = true;
    indptr.assign(N + 1, 0);
    for (auto&& e: edges) {
      indptr[e.frm + 1]++;
      if (!directed) indptr[e.to + 1]++;
    }
    for (int v = 0; v < N; ++v) { indptr[v + 1] += indptr[v]; }
    auto counter = indptr;
    csr_edges.resize(indptr.back() + 1);
    for (auto&& e: edges) {
      csr_edges[counter[e.frm]++] = e;
      if (!directed)
        csr_edges[counter[e.to]++] = edge_type({e.to, e.frm, e.cost, e.id});
    }
  }

  OutgoingEdges operator[](int v) const {
    assert(prepared);
    return {this, indptr[v], indptr[v + 1]};
  }

  vc<int> deg_array() {
    if (vc_deg.empty()) calc_deg();
    return vc_deg;
  }

  pair<vc<int>, vc<int>> deg_array_inout() {
    if (vc_indeg.empty()) calc_deg_inout();
    return {vc_indeg, vc_outdeg};
  }

  int deg(int v) {
    if (vc_deg.empty()) calc_deg();
    return vc_deg[v];
  }

  int in_deg(int v) {
    if (vc_indeg.empty()) calc_deg_inout();
    return vc_indeg[v];
  }

  int out_deg(int v) {
    if (vc_outdeg.empty()) calc_deg_inout();
    return vc_outdeg[v];
  }

  void debug() {
    print("Graph");
    if (!prepared) {
      print("frm to cost id");
      for (auto&& e: edges) print(e.frm, e.to, e.cost, e.id);
    } else {
      print("indptr", indptr);
      print("frm to cost id");
      FOR(v, N) for (auto&& e: (*this)[v]) print(e.frm, e.to, e.cost, e.id);
    }
  }

  // G における頂点 V[i] が、新しいグラフで i になるようにする
  // {G, es}
  pair<Graph<T, directed>, vc<int>> rearrange(vc<int> V) {
    int n = len(V);
    map<int, int> MP;
    FOR(i, n) MP[V[i]] = i;
    set<int> used;
    Graph<T, directed> G(n);
    vc<int> es;
    FOR(i, n) {
      for (auto&& e: (*this)[V[i]]) {
        if (used.count(e.id)) continue;
        int a = e.frm, b = e.to;
        if (MP.count(a) && MP.count(b)) {
          used.insert(e.id);
          G.add(MP[a], MP[b], e.cost);
          es.eb(e.id);
        }
      }
    }
    G.build();
    return {G, es};
  }

private:
  void calc_deg() {
    assert(vc_deg.empty());
    vc_deg.resize(N);
    for (auto&& e: edges) vc_deg[e.frm]++, vc_deg[e.to]++;
  }

  void calc_deg_inout() {
    assert(vc_indeg.empty());
    vc_indeg.resize(N);
    vc_outdeg.resize(N);
    for (auto&& e: edges) { vc_indeg[e.to]++, vc_outdeg[e.frm]++; }
  }
};
#line 3 "library/graph/strongly_connected_component.hpp"

template <typename Graph>
pair<int, vc<int>> strongly_connected_component(Graph& G) {
  assert(G.is_directed());
  assert(G.is_prepared());
  int N = G.N;
  int C = 0;
  vc<int> comp(N);
  vc<int> low(N);
  vc<int> ord(N, -1);
  vc<int> visited;
  int now = 0;

  auto dfs = [&](auto self, int v) -> void {
    low[v] = now;
    ord[v] = now;
    ++now;
    visited.eb(v);
    for (auto&& [frm, to, cost, id]: G[v]) {
      if (ord[to] == -1) {
        self(self, to);
        chmin(low[v], low[to]);
      } else {
        chmin(low[v], ord[to]);
      }
    }
    if (low[v] == ord[v]) {
      while (1) {
        int u = visited.back();
        visited.pop_back();
        ord[u] = N;
        comp[u] = C;
        if (u == v) break;
      }
      ++C;
    }
  };
  FOR(v, N) {
    if (ord[v] == -1) dfs(dfs, v);
  }
  FOR(v, N) comp[v] = C - 1 - comp[v];
  return {C, comp};
}

template <typename GT>
Graph<int, 1> scc_dag(GT& G, int C, vc<int>& comp) {
  Graph<int, 1> DAG(C);
  vvc<int> edges(C);
  for (auto&& e: G.edges) {
    int x = comp[e.frm], y = comp[e.to];
    if (x == y) continue;
    edges[x].eb(y);
  }
  FOR(c, C) {
    UNIQUE(edges[c]);
    for (auto&& to: edges[c]) DAG.add(c, to);
  }
  DAG.build();
  return DAG;
}
#line 3 "library/graph/reachability.hpp"

// 有向グラフの到達可能性クエリ。O((N+M)Q/w)。
template <typename GT, typename P>
vc<int> reachability(GT& G, vc<P> query) {
  auto [C, comp] = strongly_connected_component(G);
  Graph<int, 1> DAG(C);
  for (auto&& e: G.edges) {
    auto a = comp[e.frm], b = comp[e.to];
    assert(a <= b);
    if (a < b) DAG.add(a, b);
  }
  DAG.build();

  int Q = len(query);
  vc<u64> dp(C);
  vc<int> res(Q);
  for (int l = 0; l < Q; l += 64) {
    int r = min(l + 64, Q);
    fill(all(dp), u64(0));

    FOR3(qid, l, r) {
      auto v = comp[query[qid].fi];
      dp[v] |= u64(1) << (qid - l);
    }
    FOR(v, C) for (auto&& e: DAG[v]) { dp[e.to] |= dp[v]; }
    FOR3(qid, l, r) {
      auto v = comp[query[qid].se];
      if (dp[v] & (u64(1) << (qid - l))) res[qid] = 1;
    }
  }
  return res;
}
#line 3 "library/graph/shortest_path/dijkstra.hpp"

template <typename T, typename GT>
pair<vc<T>, vc<int>> dijkstra(GT& G, int v) {
  auto N = G.N;
  vector<T> dist(N, infty<T>);
  vector<int> par(N, -1);
  using P = pair<T, int>;

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

  dist[v] = 0;
  que.emplace(0, v);
  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        par[e.to] = e.frm;
        que.emplace(dist[e.to], e.to);
      }
    }
  }
  return {dist, par};
}

// 多点スタート。[dist, par, root]
template <typename T, typename GT>
tuple<vc<T>, vc<int>, vc<int>> dijkstra(GT& G, vc<int> vs) {
  assert(G.is_prepared());
  int N = G.N;
  vc<ll> dist(N, infty<T>);
  vc<int> par(N, -1);
  vc<int> root(N, -1);

  using P = pair<T, int>;

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

  for (auto&& v: vs) {
    dist[v] = 0;
    root[v] = v;
    que.emplace(T(0), v);
  }

  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        root[e.to] = root[e.frm];
        par[e.to] = e.frm;
        que.push(mp(dist[e.to], e.to));
      }
    }
  }
  return {dist, par, root};
}
#line 6 "main.cpp"

void solve() {
  LL(N, M);
  Graph<int, 0> G(N);
  G.read_graph(M, 1);
  LL(a, b);
  --a, --b;

  auto [dist_a, par_a] = dijkstra<int>(G, a);
  auto [dist_b, par_b] = dijkstra<int>(G, b);

  Graph<int, 1> DG(N);
  ll d = dist_a[b];
  for (auto&& e: G.edges) {
    if (dist_a[e.frm] + e.cost + dist_b[e.to] == d) DG.add(e.frm, e.to);
    if (dist_b[e.frm] + e.cost + dist_a[e.to] == d) DG.add(e.to, e.frm);
  }
  DG.build();

  LL(Q);
  VEC(pi, query, Q);
  for (auto&& [a, b]: query) --a, --b;
  auto res = reachability(DG, query);
  for (auto&& yn: res) Yes(yn);
}

signed main() {
  solve();
  return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 44928
final_rank: 3

code_snippet: #line 1 "main.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0275"
#line 1 "/home/maspy/compro/library/my_template.hpp"
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pi = pair<ll, ll>;
using vi = vector<ll>;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;

template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

#define FOR_(n) for (ll _ = 0; (_) < (ll)(n); ++(_))
#define FOR(i, n) for (ll i = 0; (i) < (ll)(n); ++(i))
#define FOR3(i, m, n) for (ll i = (m); (i) < (ll)(n); ++(i))
#define FOR_R(i, n) for (ll i = (ll)(n)-1; (i) >= 0; --(i))
#define FOR3_R(i, m, n) for (ll i = (ll)(n)-1; (i) >= (ll)(m); --(i))
#define FOR_subset(t, s) for (ll t = s; t >= 0; t = (t == 0 ? -1 : (t - 1) & s))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

template <typename T>
T SUM(vector<T> &A) {
  T sum = T(0);
  for (auto &&a: A) sum += a;
  return sum;
}
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T, typename U>
T ceil(T x, U y) {
  return (x > 0 ? (x + y - 1) / y : x / y);
}

template <typename T, typename U>
T floor(T x, U y) {
  return (x > 0 ? x / y : (x - y + 1) / y);
}

template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

ll binary_search(function<bool(ll)> check, ll ok, ll ng) {
  assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    if (check(x))
      ok = x;
    else
      ng = x;
  }
  return ok;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

vi s_to_vi(const string& S, char first_char) {
  vi A(S.size());
  FOR(i, S.size()) { A[i] = S[i] - first_char; }
  return A;
}

template <typename T>
vector<T> cumsum(vector<T> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

template <typename CNT, typename T>
vc<CNT> bincount(const vc<T> &A, int size) {
  vc<CNT> C(size);
  for (auto &&x: A) { ++C[x]; }
  return C;
}

template <typename T>
vector<int> argsort(const vector<T> &A) {
  // stable
  vector<int> ids(A.size());
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return A[i] < A[j] || (A[i] == A[j] && i < j); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  int n = len(A);
  assert(len(I) == n);
  vc<T> B(n);
  FOR(i, n) B[i] = A[I[i]];
  return B;
}
#line 1 "/home/maspy/compro/library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>

namespace detail {
template <typename T, decltype(&T::is_modint) = &T::is_modint>
std::true_type check_value(int);
template <typename T>
std::false_type check_value(long);
} // namespace detail

template <typename T>
struct is_modint : decltype(detail::check_value<T>(0)) {};
template <typename T>
using is_modint_t = enable_if_t<is_modint<T>::value>;
template <typename T>
using is_not_modint_t = enable_if_t<!is_modint<T>::value>;

struct Scanner {
  FILE *fp;
  char line[(1 << 15) + 1];
  size_t st = 0, ed = 0;
  void reread() {
    memmove(line, line + st, ed - st);
    ed -= st;
    st = 0;
    ed += fread(line + ed, 1, (1 << 15) - ed, fp);
    line[ed] = '\0';
  }
  bool succ() {
    while (true) {
      if (st == ed) {
        reread();
        if (st == ed) return false;
      }
      while (st != ed && isspace(line[st])) st++;
      if (st != ed) break;
    }
    if (ed - st <= 50) {
      bool sep = false;
      for (size_t i = st; i < ed; i++) {
        if (isspace(line[i])) {
          sep = true;
          break;
        }
      }
      if (!sep) reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    while (true) {
      size_t sz = 0;
      while (st + sz < ed && !isspace(line[st + sz])) sz++;
      ref.append(line + st, sz);
      st += sz;
      if (!sz || st != ed) break;
      reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    bool neg = false;
    if (line[st] == '-') {
      neg = true;
      st++;
    }
    ref = T(0);
    while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
    if (neg) ref = -ref;
    return true;
  }
  template <class T, is_modint_t<T> * = nullptr>
  bool read_single(T &ref) {
    long long val = 0;
    bool f = read_single(val);
    ref = T(val);
    return f;
  }
  bool read_single(double &ref) {
    string s;
    if (!read_single(s)) return false;
    ref = std::stod(s);
    return true;
  }
  bool read_single(char &ref) {
    string s;
    if (!read_single(s) || s.size() != 1) return false;
    ref = s[0];
    return true;
  }
  template <class T>
  bool read_single(vector<T> &ref) {
    for (auto &d: ref) {
      if (!read_single(d)) return false;
    }
    return true;
  }
  template <class T, class U>
  bool read_single(pair<T, U> &p) {
    return (read_single(p.first) && read_single(p.second));
  }
  template <class A, class B, class C>
  bool read_single(tuple<A, B, C> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)));
  }
  template <class A, class B, class C, class D>
  bool read_single(tuple<A, B, C, D> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)) && read_single(get<3>(p)));
  }
  void read() {}
  template <class H, class... T>
  void read(H &h, T &... t) {
    bool f = read_single(h);
    assert(f);
    read(t...);
  }
  Scanner(FILE *fp) : fp(fp) {}
};

struct Printer {
  Printer(FILE *_fp) : fp(_fp) {}
  ~Printer() { flush(); }

  static constexpr size_t SIZE = 1 << 15;
  FILE *fp;
  char line[SIZE], small[50];
  size_t pos = 0;
  void flush() {
    fwrite(line, 1, pos, fp);
    pos = 0;
  }
  void write(const char &val) {
    if (pos == SIZE) flush();
    line[pos++] = val;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  void write(T val) {
    if (pos > (1 << 15) - 50) flush();
    if (val == 0) {
      write('0');
      return;
    }
    if (val < 0) {
      write('-');
      val = -val; // todo min
    }
    size_t len = 0;
    while (val) {
      small[len++] = char(0x30 | (val % 10));
      val /= 10;
    }
    for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
    pos += len;
  }
  void write(const string &s) {
    for (char c: s) write(c);
  }
  void write(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) write(s[i]);
  }
  void write(const double &x) {
    ostringstream oss;
    oss << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  void write(const long double &x) {
    ostringstream oss;
    oss << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  template <class T, is_modint_t<T> * = nullptr>
  void write(T &ref) {
    write(ref.val);
  }
  template <class T>
  void write(const vector<T> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  template <class T, class U>
  void write(const pair<T, U> &val) {
    write(val.first);
    write(' ');
    write(val.second);
  }
  template <class A, class B, class C>
  void write(const tuple<A, B, C> &val) {
    auto &[a, b, c] = val;
    write(a), write(' '), write(b), write(' '), write(c);
  }
  template <class A, class B, class C, class D>
  void write(const tuple<A, B, C, D> &val) {
    auto &[a, b, c, d] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d);
  }
  template <class A, class B, class C, class D, class E>
  void write(const tuple<A, B, C, D, E> &val) {
    auto &[a, b, c, d, e] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e);
  }
  template <class A, class B, class C, class D, class E, class F>
  void write(const tuple<A, B, C, D, E, F> &val) {
    auto &[a, b, c, d, e, f] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e), write(' '), write(f);
  }
  template <class T, size_t S>
  void write(const array<T, S> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  void write(i128 val) {
    string s;
    bool negative = 0;
    if(val < 0){
      negative = 1;
      val = -val;
    }
    while (val) {
      s += '0' + int(val % 10);
      val /= 10;
    }
    if(negative) s += "-";
    reverse(all(s));
    if (len(s) == 0) s = "0";
    write(s);
  }
};

Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);

void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  printer.write(head);
  if (sizeof...(Tail)) printer.write(' ');
  print(forward<Tail>(tail)...);
}

void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
  scanner.read(head);
  read(tail...);
}

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)      \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 2 "/home/maspy/compro/library/graph/base.hpp"

template <typename T>
struct Edge {
  int frm, to;
  T cost;
  int id;
};

template <typename T = int, bool directed = false>
struct Graph {
  int N, M;
  using cost_type = T;
  using edge_type = Edge<T>;
  vector<edge_type> edges;
  vector<int> indptr;
  vector<edge_type> csr_edges;
  bool prepared;

  class OutgoingEdges {
  public:
    OutgoingEdges(const Graph* G, int l, int r) : G(G), l(l), r(r) {}

    const edge_type* begin() const {
      if (l == r) { return 0; }
      return &G->csr_edges[l];
    }

    const edge_type* end() const {
      if (l == r) { return 0; }
      return &G->csr_edges[r];
    }

  private:
    int l, r;
    const Graph* G;
  };

  bool is_prepared() { return prepared; }
  constexpr bool is_directed() { return directed; }

  Graph() : N(0), M(0), prepared(0) {}
  Graph(int N) : N(N), M(0), prepared(0) {}

  void add(int frm, int to, T cost = 1, int i = -1) {
    assert(!prepared && 0 <= frm && 0 <= to && to < N);
    if (i == -1) i = M;
    auto e = edge_type({frm, to, cost, i});
    edges.eb(e);
    ++M;
  }

  // wt, off
  void read_tree(bool wt = false, int off = 1) { read_graph(N - 1, wt, off); }

  void read_graph(int M, bool wt = false, int off = 1) {
    FOR_(M) {
      INT(a, b);
      a -= off, b -= off;
      if (!wt) {
        add(a, b);
      } else {
        T c;
        read(c);
        add(a, b, c);
      }
    }
    build();
  }

  void read_parent(int off = 1) {
    FOR3(v, 1, N) {
      INT(p);
      p -= off;
      add(p, v);
    }
    build();
  }

  void build() {
    assert(!prepared);
    prepared = true;
    indptr.assign(N + 1, 0);
    for (auto&& e: edges) {
      indptr[e.frm + 1]++;
      if (!directed) indptr[e.to + 1]++;
    }
    FOR(v, N) indptr[v + 1] += indptr[v];
    auto counter = indptr;
    csr_edges.resize(indptr.back() + 1);
    for (auto&& e: edges) {
      csr_edges[counter[e.frm]++] = e;
      if (!directed)
        csr_edges[counter[e.to]++] = edge_type({e.to, e.frm, e.cost, e.id});
    }
  }

  OutgoingEdges operator[](int v) const {
    assert(prepared);
    return {this, indptr[v], indptr[v + 1]};
  }

  void debug() {
    print("Graph");
    if (!prepared) {
      print("frm to cost id");
      for (auto&& e: edges) print(e.frm, e.to, e.cost, e.id);
    } else {
      print("indptr", indptr);
      print("frm to cost id");
      FOR(v, N) for (auto&& e: (*this)[v]) print(e.frm, e.to, e.cost, e.id);
    }
  }
};
#line 3 "/home/maspy/compro/library/graph/strongly_connected_component.hpp"

template <typename Graph>
pair<int, vc<int>> strongly_connected_component(Graph &G) {
  assert(G.is_directed());
  assert(G.is_prepared());
  int N = G.N;
  int C = 0;
  vc<int> comp(N);
  vc<int> low(N);
  vc<int> ord(N, -1);
  vc<int> visited;
  int now = 0;

  auto dfs = [&](auto self, int v) -> void {
    low[v] = now;
    ord[v] = now;
    ++now;
    visited.eb(v);
    for (auto &&[frm, to, cost, id]: G[v]) {
      if (ord[to] == -1) {
        self(self, to);
        chmin(low[v], low[to]);
      } else {
        chmin(low[v], ord[to]);
      }
    }
    if (low[v] == ord[v]) {
      while (1) {
        int u = visited.back();
        visited.pop_back();
        ord[u] = N;
        comp[u] = C;
        if (u == v) break;
      }
      ++C;
    }
  };
  FOR(v, N) {
    if (ord[v] == -1) dfs(dfs, v);
  }
  FOR(v, N) comp[v] = C - 1 - comp[v];
  return {C, comp};
}
#line 3 "/home/maspy/compro/library/graph/reachability.hpp"

// 有向グラフの到達可能性クエリ。O((N+M)Q/w)。
template <typename GT, typename P>
vc<int> reachability(GT& G, vc<P> query) {
  auto [C, comp] = strongly_connected_component(G);
  Graph<int, 1> DAG(C);
  for (auto&& e: G.edges) {
    auto a = comp[e.frm], b = comp[e.to];
    assert(a <= b);
    if (a < b) DAG.add(a, b);
  }
  DAG.build();

  int Q = len(query);
  vc<u64> dp(C);
  vc<int> res(Q);
  for (int l = 0; l < Q; l += 64) {
    int r = min(l + 64, Q);
    fill(all(dp), u64(0));

    FOR3(qid, l, r) {
      auto v = comp[query[qid].fi];
      dp[v] |= u64(1) << (qid - l);
    }
    FOR(v, C) for (auto&& e: DAG[v]) { dp[e.to] |= dp[v]; }
    FOR3(qid, l, r) {
      auto v = comp[query[qid].se];
      if (dp[v] & (u64(1) << (qid - l))) res[qid] = 1;
    }
  }
  return res;
}
#line 3 "/home/maspy/compro/library/graph/dijkstra.hpp"

template <typename T, typename Graph>
pair<vc<T>, vc<int>> dijkstra(Graph& G, int v, T INF) {
  auto N = G.N;
  vector<T> dist(N, INF);
  vector<int> par(N, -1);
  using P = pair<T, int>;

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

  dist[v] = 0;
  que.emplace(0, v);
  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        par[e.to] = e.frm;
        que.emplace(dist[e.to], e.to);
      }
    }
  }
  return {dist, par};
}

// 多点スタート。[dist, par, root]
template <typename T, T INF, typename Graph>
tuple<vc<T>, vc<int>, vc<int>> dijkstra(Graph& G, vc<int> vs) {
  assert(G.is_prepared());
  int N = G.N;
  vc<ll> dist(N, INF);
  vc<int> par(N, -1);
  vc<int> root(N, -1);

  using P = pair<T, int>;

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

  for (auto&& v: vs) {
    dist[v] = 0;
    root[v] = v;
    que.emplace(T(0), v);
  }

  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        root[e.to] = root[e.frm];
        par[e.to] = e.frm;
        que.push(mp(dist[e.to], e.to));
      }
    }
  }
  return {dist, par, root};
}
#line 6 "main.cpp"

void solve() {
  LL(N, M);
  Graph G(N);
  G.read_graph(M, 1);
  LL(a, b);
  --a, --b;
  const ll INF = 1LL << 60;

  auto [dist_a, par_a] = dijkstra(G, a, INF);
  auto [dist_b, par_b] = dijkstra(G, b, INF);

  Graph<int, 1> DG(N);
  ll d = dist_a[b];
  for (auto&& e: G.edges) {
    if (dist_a[e.frm] + e.cost + dist_b[e.to] == d) DG.add(e.frm, e.to);
    if (dist_b[e.frm] + e.cost + dist_a[e.to] == d) DG.add(e.to, e.frm);
  }
  DG.build();

  LL(Q);
  VEC(pi, query, Q);
  for (auto&& [a, b]: query) --a, --b;
  auto res = reachability(DG, query);
  for (auto&& yn: res) Yes(yn);
}

signed main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << setprecision(15);

  ll T = 1;
  // LL(T);
  FOR(_, T) solve();

  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 45456
final_rank: 5

code_snippet: #line 1 "/home/maspy/compro/library/my_template.hpp"
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using pi = pair<ll, ll>;
using vi = vector<ll>;
using u32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;

template <class T>
using vc = vector<T>;
template <class T>
using vvc = vector<vc<T>>;
template <class T>
using vvvc = vector<vvc<T>>;
template <class T>
using vvvvc = vector<vvvc<T>>;
template <class T>
using vvvvvc = vector<vvvvc<T>>;
template <class T>
using pq = priority_queue<T>;
template <class T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

#define vec(type, name, ...) vector<type> name(__VA_ARGS__)
#define vv(type, name, h, ...) \
  vector<vector<type>> name(h, vector<type>(__VA_ARGS__))
#define vvv(type, name, h, w, ...)   \
  vector<vector<vector<type>>> name( \
      h, vector<vector<type>>(w, vector<type>(__VA_ARGS__)))
#define vvvv(type, name, a, b, c, ...)       \
  vector<vector<vector<vector<type>>>> name( \
      a, vector<vector<vector<type>>>(       \
             b, vector<vector<type>>(c, vector<type>(__VA_ARGS__))))

#define FOR_(n) for (ll _ = 0; (_) < (ll)(n); ++(_))
#define FOR(i, n) for (ll i = 0; (i) < (ll)(n); ++(i))
#define FOR3(i, m, n) for (ll i = (m); (i) < (ll)(n); ++(i))
#define FOR_R(i, n) for (ll i = (ll)(n)-1; (i) >= 0; --(i))
#define FOR3_R(i, m, n) for (ll i = (ll)(n)-1; (i) >= (ll)(m); --(i))
#define FOR_subset(t, s) for (ll t = s; t >= 0; t = (t == 0 ? -1 : (t - 1) & s))
#define all(x) x.begin(), x.end()
#define len(x) ll(x.size())
#define elif else if

#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second

#define stoi stoll

template <typename T>
T SUM(vector<T> &A) {
  T sum = T(0);
  for (auto &&a: A) sum += a;
  return sum;
}
#define MIN(v) *min_element(all(v))
#define MAX(v) *max_element(all(v))
#define LB(c, x) distance((c).begin(), lower_bound(all(c), (x)))
#define UB(c, x) distance((c).begin(), upper_bound(all(c), (x)))
#define UNIQUE(x) sort(all(x)), x.erase(unique(all(x)), x.end())

int popcnt(int x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(ll x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 1, 2)
int topbit(int x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(u32 x) { return (x == 0 ? -1 : 31 - __builtin_clz(x)); }
int topbit(ll x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
int topbit(u64 x) { return (x == 0 ? -1 : 63 - __builtin_clzll(x)); }
// (0, 1, 2, 3, 4) -> (-1, 0, 1, 0, 2)
int lowbit(int x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(u32 x) { return (x == 0 ? -1 : __builtin_ctz(x)); }
int lowbit(ll x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }
int lowbit(u64 x) { return (x == 0 ? -1 : __builtin_ctzll(x)); }

template <typename T, typename U>
T ceil(T x, U y) {
  return (x > 0 ? (x + y - 1) / y : x / y);
}

template <typename T, typename U>
T floor(T x, U y) {
  return (x > 0 ? x / y : (x - y + 1) / y);
}

template <typename T, typename U>
pair<T, T> divmod(T x, U y) {
  T q = floor(x, y);
  return {q, x - q * y};
}

ll binary_search(function<bool(ll)> check, ll ok, ll ng) {
  assert(check(ok));
  while (abs(ok - ng) > 1) {
    auto x = (ng + ok) / 2;
    if (check(x))
      ok = x;
    else
      ng = x;
  }
  return ok;
}

template <class T, class S>
inline bool chmax(T &a, const S &b) {
  return (a < b ? a = b, 1 : 0);
}
template <class T, class S>
inline bool chmin(T &a, const S &b) {
  return (a > b ? a = b, 1 : 0);
}

vi s_to_vi(const string& S, char first_char) {
  vi A(S.size());
  FOR(i, S.size()) { A[i] = S[i] - first_char; }
  return A;
}

template <typename T>
vector<T> cumsum(vector<T> &A, int off = 1) {
  int N = A.size();
  vector<T> B(N + 1);
  FOR(i, N) { B[i + 1] = B[i] + A[i]; }
  if (off == 0) B.erase(B.begin());
  return B;
}

template <typename CNT, typename T>
vc<CNT> bincount(const vc<T> &A, int size) {
  vc<CNT> C(size);
  for (auto &&x: A) { ++C[x]; }
  return C;
}

template <typename T>
vector<int> argsort(const vector<T> &A) {
  // stable
  vector<int> ids(A.size());
  iota(all(ids), 0);
  sort(all(ids),
       [&](int i, int j) { return A[i] < A[j] || (A[i] == A[j] && i < j); });
  return ids;
}

// A[I[0]], A[I[1]], ...
template <typename T>
vc<T> rearrange(const vc<T> &A, const vc<int> &I) {
  int n = len(A);
  assert(len(I) == n);
  vc<T> B(n);
  FOR(i, n) B[i] = A[I[i]];
  return B;
}
#line 1 "/home/maspy/compro/library/other/io.hpp"
// based on yosupo's fastio
#include <unistd.h>

namespace detail {
template <typename T, decltype(&T::is_modint) = &T::is_modint>
std::true_type check_value(int);
template <typename T>
std::false_type check_value(long);
} // namespace detail

template <typename T>
struct is_modint : decltype(detail::check_value<T>(0)) {};
template <typename T>
using is_modint_t = enable_if_t<is_modint<T>::value>;
template <typename T>
using is_not_modint_t = enable_if_t<!is_modint<T>::value>;

struct Scanner {
  FILE *fp;
  char line[(1 << 15) + 1];
  size_t st = 0, ed = 0;
  void reread() {
    memmove(line, line + st, ed - st);
    ed -= st;
    st = 0;
    ed += fread(line + ed, 1, (1 << 15) - ed, fp);
    line[ed] = '\0';
  }
  bool succ() {
    while (true) {
      if (st == ed) {
        reread();
        if (st == ed) return false;
      }
      while (st != ed && isspace(line[st])) st++;
      if (st != ed) break;
    }
    if (ed - st <= 50) {
      bool sep = false;
      for (size_t i = st; i < ed; i++) {
        if (isspace(line[i])) {
          sep = true;
          break;
        }
      }
      if (!sep) reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    while (true) {
      size_t sz = 0;
      while (st + sz < ed && !isspace(line[st + sz])) sz++;
      ref.append(line + st, sz);
      st += sz;
      if (!sz || st != ed) break;
      reread();
    }
    return true;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  bool read_single(T &ref) {
    if (!succ()) return false;
    bool neg = false;
    if (line[st] == '-') {
      neg = true;
      st++;
    }
    ref = T(0);
    while (isdigit(line[st])) { ref = 10 * ref + (line[st++] & 0xf); }
    if (neg) ref = -ref;
    return true;
  }
  template <class T, is_modint_t<T> * = nullptr>
  bool read_single(T &ref) {
    long long val = 0;
    bool f = read_single(val);
    ref = T(val);
    return f;
  }
  bool read_single(double &ref) {
    string s;
    if (!read_single(s)) return false;
    ref = std::stod(s);
    return true;
  }
  bool read_single(char &ref) {
    string s;
    if (!read_single(s) || s.size() != 1) return false;
    ref = s[0];
    return true;
  }
  template <class T>
  bool read_single(vector<T> &ref) {
    for (auto &d: ref) {
      if (!read_single(d)) return false;
    }
    return true;
  }
  template <class T, class U>
  bool read_single(pair<T, U> &p) {
    return (read_single(p.first) && read_single(p.second));
  }
  template <class A, class B, class C>
  bool read_single(tuple<A, B, C> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)));
  }
  template <class A, class B, class C, class D>
  bool read_single(tuple<A, B, C, D> &p) {
    return (read_single(get<0>(p)) && read_single(get<1>(p))
            && read_single(get<2>(p)) && read_single(get<3>(p)));
  }
  void read() {}
  template <class H, class... T>
  void read(H &h, T &... t) {
    bool f = read_single(h);
    assert(f);
    read(t...);
  }
  Scanner(FILE *fp) : fp(fp) {}
};

struct Printer {
  Printer(FILE *_fp) : fp(_fp) {}
  ~Printer() { flush(); }

  static constexpr size_t SIZE = 1 << 15;
  FILE *fp;
  char line[SIZE], small[50];
  size_t pos = 0;
  void flush() {
    fwrite(line, 1, pos, fp);
    pos = 0;
  }
  void write(const char &val) {
    if (pos == SIZE) flush();
    line[pos++] = val;
  }
  template <class T, enable_if_t<is_integral<T>::value, int> = 0>
  void write(T val) {
    if (pos > (1 << 15) - 50) flush();
    if (val == 0) {
      write('0');
      return;
    }
    if (val < 0) {
      write('-');
      val = -val; // todo min
    }
    size_t len = 0;
    while (val) {
      small[len++] = char(0x30 | (val % 10));
      val /= 10;
    }
    for (size_t i = 0; i < len; i++) { line[pos + i] = small[len - 1 - i]; }
    pos += len;
  }
  void write(const string &s) {
    for (char c: s) write(c);
  }
  void write(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) write(s[i]);
  }
  void write(const double &x) {
    ostringstream oss;
    oss << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  void write(const long double &x) {
    ostringstream oss;
    oss << setprecision(15) << x;
    string s = oss.str();
    write(s);
  }
  template <class T, is_modint_t<T> * = nullptr>
  void write(T &ref) {
    write(ref.val);
  }
  template <class T>
  void write(const vector<T> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  template <class T, class U>
  void write(const pair<T, U> &val) {
    write(val.first);
    write(' ');
    write(val.second);
  }
  template <class A, class B, class C>
  void write(const tuple<A, B, C> &val) {
    auto &[a, b, c] = val;
    write(a), write(' '), write(b), write(' '), write(c);
  }
  template <class A, class B, class C, class D>
  void write(const tuple<A, B, C, D> &val) {
    auto &[a, b, c, d] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d);
  }
  template <class A, class B, class C, class D, class E>
  void write(const tuple<A, B, C, D, E> &val) {
    auto &[a, b, c, d, e] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e);
  }
  template <class A, class B, class C, class D, class E, class F>
  void write(const tuple<A, B, C, D, E, F> &val) {
    auto &[a, b, c, d, e, f] = val;
    write(a), write(' '), write(b), write(' '), write(c), write(' '), write(d), write(' '), write(e), write(' '), write(f);
  }
  template <class T, size_t S>
  void write(const array<T, S> &val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
      if (i) write(' ');
      write(val[i]);
    }
  }
  void write(i128 val) {
    string s;
    bool negative = 0;
    if(val < 0){
      negative = 1;
      val = -val;
    }
    while (val) {
      s += '0' + int(val % 10);
      val /= 10;
    }
    if(negative) s += "-";
    reverse(all(s));
    if (len(s) == 0) s = "0";
    write(s);
  }
};

Scanner scanner = Scanner(stdin);
Printer printer = Printer(stdout);

void flush() { printer.flush(); }
void print() { printer.write('\n'); }
template <class Head, class... Tail>
void print(Head &&head, Tail &&... tail) {
  printer.write(head);
  if (sizeof...(Tail)) printer.write(' ');
  print(forward<Tail>(tail)...);
}

void read() {}
template <class Head, class... Tail>
void read(Head &head, Tail &... tail) {
  scanner.read(head);
  read(tail...);
}

#define INT(...)   \
  int __VA_ARGS__; \
  read(__VA_ARGS__)
#define LL(...)   \
  ll __VA_ARGS__; \
  read(__VA_ARGS__)
#define STR(...)      \
  string __VA_ARGS__; \
  read(__VA_ARGS__)
#define CHAR(...)      \
  char __VA_ARGS__; \
  read(__VA_ARGS__)
#define DBL(...)      \
  double __VA_ARGS__; \
  read(__VA_ARGS__)

#define VEC(type, name, size) \
  vector<type> name(size);    \
  read(name)
#define VV(type, name, h, w)                     \
  vector<vector<type>> name(h, vector<type>(w)); \
  read(name)

void YES(bool t = 1) { print(t ? "YES" : "NO"); }
void NO(bool t = 1) { YES(!t); }
void Yes(bool t = 1) { print(t ? "Yes" : "No"); }
void No(bool t = 1) { Yes(!t); }
void yes(bool t = 1) { print(t ? "yes" : "no"); }
void no(bool t = 1) { yes(!t); }
#line 2 "/home/maspy/compro/library/graph/base.hpp"

template <typename T>
struct Edge {
  int frm, to;
  T cost;
  int id;
};

template <typename T = int, bool directed = false>
struct Graph {
  int N, M;
  using cost_type = T;
  using edge_type = Edge<T>;
  vector<edge_type> edges;
  vector<int> indptr;
  vector<edge_type> csr_edges;
  bool prepared;

  class OutgoingEdges {
  public:
    OutgoingEdges(const Graph* G, int l, int r) : G(G), l(l), r(r) {}

    const edge_type* begin() const {
      if (l == r) { return 0; }
      return &G->csr_edges[l];
    }

    const edge_type* end() const {
      if (l == r) { return 0; }
      return &G->csr_edges[r];
    }

  private:
    int l, r;
    const Graph* G;
  };

  bool is_prepared() { return prepared; }
  constexpr bool is_directed() { return directed; }

  Graph() : N(0), M(0), prepared(0) {}
  Graph(int N) : N(N), M(0), prepared(0) {}

  void add(int frm, int to, T cost = 1, int i = -1) {
    assert(!prepared && 0 <= frm && 0 <= to && to < N);
    if (i == -1) i = M;
    auto e = edge_type({frm, to, cost, i});
    edges.eb(e);
    ++M;
  }

  // wt, off
  void read_tree(bool wt = false, int off = 1) { read_graph(N - 1, wt, off); }

  void read_graph(int M, bool wt = false, int off = 1) {
    FOR_(M) {
      INT(a, b);
      a -= off, b -= off;
      if (!wt) {
        add(a, b);
      } else {
        T c;
        read(c);
        add(a, b, c);
      }
    }
    build();
  }

  void read_parent(int off = 1) {
    FOR3(v, 1, N) {
      INT(p);
      p -= off;
      add(p, v);
    }
    build();
  }

  void build() {
    assert(!prepared);
    prepared = true;
    indptr.assign(N + 1, 0);
    for (auto&& e: edges) {
      indptr[e.frm + 1]++;
      if (!directed) indptr[e.to + 1]++;
    }
    FOR(v, N) indptr[v + 1] += indptr[v];
    auto counter = indptr;
    csr_edges.resize(indptr.back() + 1);
    for (auto&& e: edges) {
      csr_edges[counter[e.frm]++] = e;
      if (!directed)
        csr_edges[counter[e.to]++] = edge_type({e.to, e.frm, e.cost, e.id});
    }
  }

  OutgoingEdges operator[](int v) const {
    assert(prepared);
    return {this, indptr[v], indptr[v + 1]};
  }

  void debug() {
    print("Graph");
    if (!prepared) {
      print("frm to cost id");
      for (auto&& e: edges) print(e.frm, e.to, e.cost, e.id);
    } else {
      print("indptr", indptr);
      print("frm to cost id");
      FOR(v, N) for (auto&& e: (*this)[v]) print(e.frm, e.to, e.cost, e.id);
    }
  }
};
#line 3 "/home/maspy/compro/library/graph/strongly_connected_component.hpp"

template <typename Graph>
pair<int, vc<int>> strongly_connected_component(Graph &G) {
  assert(G.is_directed());
  assert(G.is_prepared());
  int N = G.N;
  int C = 0;
  vc<int> comp(N);
  vc<int> low(N);
  vc<int> ord(N, -1);
  vc<int> visited;
  int now = 0;

  auto dfs = [&](auto self, int v) -> void {
    low[v] = now;
    ord[v] = now;
    ++now;
    visited.eb(v);
    for (auto &&[frm, to, cost, id]: G[v]) {
      if (ord[to] == -1) {
        self(self, to);
        chmin(low[v], low[to]);
      } else {
        chmin(low[v], ord[to]);
      }
    }
    if (low[v] == ord[v]) {
      while (1) {
        int u = visited.back();
        visited.pop_back();
        ord[u] = N;
        comp[u] = C;
        if (u == v) break;
      }
      ++C;
    }
  };
  FOR(v, N) {
    if (ord[v] == -1) dfs(dfs, v);
  }
  FOR(v, N) comp[v] = C - 1 - comp[v];
  return {C, comp};
}
#line 3 "/home/maspy/compro/library/graph/dijkstra.hpp"

template <typename T, typename Graph>
pair<vc<T>, vc<int>> dijkstra(Graph& G, int v, T INF) {
  auto N = G.N;
  vector<T> dist(N, INF);
  vector<int> par(N, -1);
  using P = pair<T, int>;

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

  dist[v] = 0;
  que.emplace(0, v);
  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        par[e.to] = e.frm;
        que.emplace(dist[e.to], e.to);
      }
    }
  }
  return {dist, par};
}

// 多点スタート。[dist, par, root]
template <typename T, T INF, typename Graph>
tuple<vc<T>, vc<int>, vc<int>> dijkstra(Graph& G, vc<int> vs) {
  assert(G.is_prepared());
  int N = G.N;
  vc<ll> dist(N, INF);
  vc<int> par(N, -1);
  vc<int> root(N, -1);

  using P = pair<T, int>;

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

  for (auto&& v: vs) {
    dist[v] = 0;
    root[v] = v;
    que.emplace(T(0), v);
  }

  while (!que.empty()) {
    auto [dv, v] = que.top();
    que.pop();
    if (dv > dist[v]) continue;
    for (auto&& e: G[v]) {
      if (chmin(dist[e.to], dist[e.frm] + e.cost)) {
        root[e.to] = root[e.frm];
        par[e.to] = e.frm;
        que.push(mp(dist[e.to], e.to));
      }
    }
  }
  return {dist, par, root};
}
#line 5 "main.cpp"

template <typename GT, typename P>
vc<int> digraph_reachability(GT& G, vc<P> query) {
  auto [C, comp] = strongly_connected_component(G);
  Graph<int, 1> DAG(C);
  for (auto&& e: G.edges) {
    auto a = comp[e.frm], b = comp[e.to];
    assert(a <= b);
    if (a < b) DAG.add(a, b);
  }
  DAG.build();

  int Q = len(query);
  vc<u64> dp(C);
  vc<int> res(Q);
  for (int l = 0; l < Q; l += 64) {
    int r = min(l + 64, Q);
    fill(all(dp), u64(0));

    FOR3(qid, l, r) {
      auto v = comp[query[qid].fi];
      dp[v] |= u64(1) << (qid - l);
    }
    FOR(v, C) for (auto&& e: DAG[v]) { dp[e.to] |= dp[v]; }
    FOR3(qid, l, r) {
      auto v = comp[query[qid].se];
      if (dp[v] & (u64(1) << (qid - l))) res[qid] = 1;
    }
  }
  return res;
}

void solve() {
  LL(N, M);
  Graph G(N);
  G.read_graph(M, 1);
  LL(a, b);
  --a, --b;
  const ll INF = 1LL << 60;

  auto [dist_a, par_a] = dijkstra(G, a, INF);
  auto [dist_b, par_b] = dijkstra(G, b, INF);

  Graph<int, 1> DG(N);
  ll d = dist_a[b];
  for (auto&& e: G.edges) {
    if (dist_a[e.frm] + e.cost + dist_b[e.to] == d) DG.add(e.frm, e.to);
    if (dist_b[e.frm] + e.cost + dist_a[e.to] == d) DG.add(e.to, e.frm);
  }
  DG.build();

  LL(Q);
  VEC(pi, query, Q);
  for (auto&& [a, b]: query) --a, --b;
  auto res = digraph_reachability(DG, query);
  for (auto&& yn: res) Yes(yn);
}

signed main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << setprecision(15);

  ll T = 1;
  // LL(T);
  FOR(_, T) solve();

  return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 45152
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;
int main(){
  int S, R;
  cin >> S >> R;
  vector<vector<pair<int, int>>> E(S);
  for (int i = 0; i < R; i++){
    int u, v, w;
    cin >> u >> v >> w;
    u--;
    v--;
    E[u].push_back(make_pair(w, v));
    E[v].push_back(make_pair(w, u));
  }
  int a, b, Q;
  cin >> a >> b >> Q;
  a--;
  b--;
  vector<int> c(Q), d(Q);
  for (int i = 0; i < Q; i++){
    cin >> c[i] >> d[i];
    c[i]--;
    d[i]--;
  }
  vector<int> d1(S, -1);
  priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq1;
  pq1.push(make_pair(0, a));
  vector<int> t;
  while (!pq1.empty()){
    int d = pq1.top().first;
    int v = pq1.top().second;
    pq1.pop();
    if (d1[v] == -1){
      d1[v] = d;
      t.push_back(v);
      for (auto P : E[v]){
        int w = P.second;
        if (d1[w] == -1){
          pq1.push(make_pair(d + P.first, w));
        }
      }
    }
  }
  vector<int> d2(S, -1);
  priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq2;
  pq2.push(make_pair(0, b));
  while (!pq2.empty()){
    int d = pq2.top().first;
    int v = pq2.top().second;
    pq2.pop();
    if (d2[v] == -1){
      d2[v] = d;
      for (auto P : E[v]){
        int w = P.second;
        if (d2[w] == -1){
          pq2.push(make_pair(d + P.first, w));
        }
      }
    }
  }
  int D = d1[b];
  vector<bool> ok(S, false);
  for (int i = 0; i < S; i++){
    if (d1[i] + d2[i] == D){
      ok[i] = true;
    }
  }
  vector<vector<int>> E2(S);
  for (int i = 0; i < S; i++){
    if (ok[i]){
      for (auto P : E[i]){
        int w = P.second;
        if (ok[w] && d1[w] == d1[i] + P.first){
          E2[i].push_back(w);
        }
      }
    }
  }
  int Q2 = (Q + 63) / 64;
  for (int i = 0; i < Q2; i++){
    int l = i * 64;
    int r = min((i + 1) * 64, Q);
    vector<unsigned long long> dp(S);
    for (int j = l; j < r; j++){
      dp[c[j]] |= (unsigned long long) 1 << (j - l);
    }
    for (int v : t){
      for (int w : E2[v]){
        dp[w] |= dp[v];
      }
    }
    for (int j = l; j < r; j++){
      if ((dp[d[j]] >> (j - l) & 1) == 1){
        cout << "Yes" << endl;
      } else {
        cout << "No" << endl;
      }
    }
  }
}
accuracy: 1
time_ms: 280
memory_kb: 19948
final_rank: 1

code_snippet: #include<cstdio>
#include<vector>
#include<queue>
using namespace std;
int N,M,S,T,Q;
vector<pair<int,int> >G[1<<17];
int dS[1<<17],dT[1<<17];
int D[1<<17],vis[1<<17];
main()
{
	scanf("%d%d",&N,&M);
	for(int i=0;i<M;i++)
	{
		int u,v,w;scanf("%d%d%d",&u,&v,&w);
		u--,v--;
		G[u].push_back(make_pair(v,w));
		G[v].push_back(make_pair(u,w));
	}
	scanf("%d%d%d",&S,&T,&Q);
	S--,T--;
	{
		for(int i=0;i<N;i++)dS[i]=dT[i]=1e9;
		{
			dS[S]=0;
			priority_queue<pair<int,int> >P;
			P.push(make_pair(0,S));
			while(!P.empty())
			{
				int cost=-P.top().first,u=P.top().second;
				P.pop();
				if(dS[u]<cost)continue;
				for(const pair<int,int>&e:G[u])
				{
					int v=e.first;
					int nxt=cost+e.second;
					if(dS[v]>nxt)
					{
						dS[v]=nxt;
						P.push(make_pair(-nxt,v));
					}
				}
			}
		}
		{
			dT[T]=0;
			priority_queue<pair<int,int> >P;
			P.push(make_pair(0,T));
			while(!P.empty())
			{
				int cost=-P.top().first,u=P.top().second;
				P.pop();
				if(dT[u]<cost)continue;
				for(const pair<int,int>&e:G[u])
				{
					int v=e.first;
					int nxt=cost+e.second;
					if(dT[v]>nxt)
					{
						dT[v]=nxt;
						P.push(make_pair(-nxt,v));
					}
				}
			}
		}
	}
	for(int tm=0;tm++<Q;)
	{
		int c,d;scanf("%d%d",&c,&d);c--,d--;
		if(dS[c]+dT[c]!=dS[T]||dS[d]+dT[d]!=dS[T])
		{
			puts("No");
			continue;
		}
		vis[c]=tm;
		D[c]=0;
		queue<int>P;
		P.push(c);
		while(!P.empty())
		{
			int u=P.front();
			P.pop();
			if(u==d)break;
			if(dS[c]+D[u]>dS[d])continue;
			for(const pair<int,int>&e:G[u])
			{
				int v=e.first,nxt=D[u]+e.second;
				if(dS[v]==dS[c]+nxt&&vis[v]<tm)
				{
					vis[v]=tm;
					D[v]=nxt;
					P.push(v);
				}
			}
		}
		puts(vis[d]==tm?"Yes":"No");
	}
}
accuracy: 1
time_ms: 910
memory_kb: 11460
final_rank: 6

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#line 2 "/home/kotatsugame/library/datastructure/UF.cpp"
struct UF{
	int n;
	vector<int>parent,rank;
	UF(int n_=0):n(n_),parent(n_),rank(n_,1)
	{
		for(int i=0;i<n_;i++)parent[i]=i;
	}
	int find(int a){return parent[a]!=a?parent[a]=find(parent[a]):a;}
	bool same(int a,int b){return find(a)==find(b);}
	bool unite(int a,int b)
	{
		a=find(a),b=find(b);
		if(a==b)return false;
		if(rank[a]<rank[b])
		{
			parent[a]=b;
			rank[b]+=rank[a];
		}
		else
		{
			parent[b]=a;
			rank[a]+=rank[b];
		}
		return true;
	}
	int size(int a){return rank[find(a)];}
};
#line 6 "a.cpp"
int N,M,s,g,Q;
vector<pair<int,int> >G[1<<17];
vector<int>dist(int st)
{
	vector<int>ret(N,1e9);
	ret[st]=0;
	priority_queue<pair<int,int> >P;
	P.push(make_pair(0,st));
	while(!P.empty())
	{
		int cost=-P.top().first,u=P.top().second;
		P.pop();
		if(ret[u]<cost)continue;
		for(pair<int,int>e:G[u])
		{
			int v=e.first,nxt=cost+e.second;
			if(ret[v]>nxt)
			{
				ret[v]=nxt;
				P.push(make_pair(-nxt,v));
			}
		}
	}
	return ret;
}
main()
{
	cin>>N>>M;
	for(int i=0;i<M;i++)
	{
		int a,b,c;cin>>a>>b>>c;
		a--,b--;
		G[a].push_back(make_pair(b,c));
		G[b].push_back(make_pair(a,c));
	}
	cin>>s>>g>>Q;
	s--,g--;
	vector<int>ds=dist(s),dg=dist(g);
	vector<vector<int> >H(N);
	vector<int>indeg(N);
	UF uf(N);
	for(int i=0;i<N;i++)for(pair<int,int>e:G[i])
	{
		int u=i,v=e.first;
		if(ds[u]+e.second+dg[v]==ds[g])
		{
			H[u].push_back(v);
			indeg[v]++;
			if(u!=s&&v!=g)uf.unite(u,v);
		}
	}
	priority_queue<pair<int,int> >P;
	for(int i=0;i<N;i++)if(!indeg[i])P.push(make_pair(ds[i],i));
	vector<int>sor;
	vector<int>sorrev(N,1e9);
	while(!P.empty())
	{
		int u=P.top().second;P.pop();
		sorrev[u]=sor.size();
		sor.push_back(u);
		for(int v:H[u])if(!--indeg[v])
		{
			P.push(make_pair(ds[v],v));
		}
	}
	for(;Q--;)
	{
		int a,b;cin>>a>>b;a--,b--;
		if(ds[a]+dg[a]!=ds[g]||ds[b]+dg[b]!=ds[g])
		{
			cout<<"No"<<endl;
			continue;
		}
		if(ds[a]<ds[b]&&dg[a]>dg[b]&&(a==s||b==g||uf.same(a,b))&&sorrev[a]<sorrev[b])cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}
accuracy: 0.8888888888888888
time_ms: 150
memory_kb: 19612
final_rank: 8

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#line 2 "/home/kotatsugame/library/datastructure/UF.cpp"
struct UF{
	int n;
	vector<int>parent,rank;
	UF(int n_=0):n(n_),parent(n_),rank(n_,1)
	{
		for(int i=0;i<n_;i++)parent[i]=i;
	}
	int find(int a){return parent[a]!=a?parent[a]=find(parent[a]):a;}
	bool same(int a,int b){return find(a)==find(b);}
	bool unite(int a,int b)
	{
		a=find(a),b=find(b);
		if(a==b)return false;
		if(rank[a]<rank[b])
		{
			parent[a]=b;
			rank[b]+=rank[a];
		}
		else
		{
			parent[b]=a;
			rank[a]+=rank[b];
		}
		return true;
	}
	int size(int a){return rank[find(a)];}
};
#line 6 "a.cpp"
int N,M,s,g,Q;
vector<pair<int,int> >G[1<<17];
vector<int>dist(int st)
{
	vector<int>ret(N,1e9);
	ret[st]=0;
	priority_queue<pair<int,int> >P;
	P.push(make_pair(0,st));
	while(!P.empty())
	{
		int cost=-P.top().first,u=P.top().second;
		P.pop();
		if(ret[u]<cost)continue;
		for(pair<int,int>e:G[u])
		{
			int v=e.first,nxt=cost+e.second;
			if(ret[v]>nxt)
			{
				ret[v]=nxt;
				P.push(make_pair(-nxt,v));
			}
		}
	}
	return ret;
}
main()
{
	cin>>N>>M;
	for(int i=0;i<M;i++)
	{
		int a,b,c;cin>>a>>b>>c;
		a--,b--;
		G[a].push_back(make_pair(b,c));
		G[b].push_back(make_pair(a,c));
	}
	cin>>s>>g>>Q;
	s--,g--;
	vector<int>ds=dist(s),dg=dist(g);
	vector<vector<int> >H(N);
	vector<int>indeg(N);
	UF uf(N);
	for(int i=0;i<N;i++)for(pair<int,int>e:G[i])
	{
		int u=i,v=e.first;
		if(ds[u]+e.second+dg[v]==ds[g])
		{
			H[u].push_back(v);
			indeg[v]++;
			if(u!=s&&v!=g)uf.unite(u,v);
		}
	}
	priority_queue<pair<int,int> >P;
	for(int i=0;i<N;i++)if(!indeg[i])P.push(make_pair(-ds[i],i));
	vector<int>sor;
	vector<int>sorrev(N,1e9);
	while(!P.empty())
	{
		int u=P.top().second;P.pop();
		sorrev[u]=sor.size();
		sor.push_back(u);
		for(int v:H[u])if(!--indeg[v])
		{
			P.push(make_pair(-ds[v],v));
		}
	}
	for(;Q--;)
	{
		int a,b;cin>>a>>b;a--,b--;
		if(ds[a]+dg[a]!=ds[g]||ds[b]+dg[b]!=ds[g])
		{
			cout<<"No"<<endl;
			continue;
		}
		if(ds[a]<ds[b]&&(a==s||b==g||uf.same(a,b))&&sorrev[a]<sorrev[b])cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}
accuracy: 0.6666666666666666
time_ms: 140
memory_kb: 15732
final_rank: 11

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#line 2 "/home/kotatsugame/library/datastructure/UF.cpp"
struct UF{
	int n;
	vector<int>parent,rank;
	UF(int n_=0):n(n_),parent(n_),rank(n_,1)
	{
		for(int i=0;i<n_;i++)parent[i]=i;
	}
	int find(int a){return parent[a]!=a?parent[a]=find(parent[a]):a;}
	bool same(int a,int b){return find(a)==find(b);}
	bool unite(int a,int b)
	{
		a=find(a),b=find(b);
		if(a==b)return false;
		if(rank[a]<rank[b])
		{
			parent[a]=b;
			rank[b]+=rank[a];
		}
		else
		{
			parent[b]=a;
			rank[a]+=rank[b];
		}
		return true;
	}
	int size(int a){return rank[find(a)];}
};
#line 6 "a.cpp"
int N,M,s,g,Q;
vector<pair<int,int> >G[1<<17];
vector<int>dist(int st)
{
	vector<int>ret(N,1e9);
	ret[st]=0;
	priority_queue<pair<int,int> >P;
	P.push(make_pair(0,st));
	while(!P.empty())
	{
		int cost=-P.top().first,u=P.top().second;
		P.pop();
		if(ret[u]<cost)continue;
		for(pair<int,int>e:G[u])
		{
			int v=e.first,nxt=cost+e.second;
			if(ret[v]>nxt)
			{
				ret[v]=nxt;
				P.push(make_pair(-nxt,v));
			}
		}
	}
	return ret;
}
main()
{
	cin>>N>>M;
	for(int i=0;i<M;i++)
	{
		int a,b,c;cin>>a>>b>>c;
		a--,b--;
		G[a].push_back(make_pair(b,c));
		G[b].push_back(make_pair(a,c));
	}
	cin>>s>>g>>Q;
	s--,g--;
	vector<int>ds=dist(s),dg=dist(g);
	vector<vector<int> >H(N);
	vector<int>indeg(N);
	UF uf(N);
	for(int i=0;i<N;i++)for(pair<int,int>e:G[i])
	{
		int u=i,v=e.first;
		if(ds[u]+e.second+dg[v]==ds[g])
		{
			H[u].push_back(v);
			indeg[v]++;
			if(u!=s&&v!=g)uf.unite(u,v);
		}
	}
	priority_queue<pair<int,int> >P;
	for(int i=0;i<N;i++)if(!indeg[i])P.push(make_pair(ds[i],i));
	vector<int>sor;
	vector<int>sorrev(N,1e9);
	while(!P.empty())
	{
		int u=P.top().second;P.pop();
		sorrev[u]=sor.size();
		sor.push_back(u);
		for(int v:H[u])if(!--indeg[v])
		{
			P.push(make_pair(ds[v],v));
		}
	}
	for(;Q--;)
	{
		int a,b;cin>>a>>b;a--,b--;
		if(ds[a]+dg[a]!=ds[g]||ds[b]+dg[b]!=ds[g])
		{
			cout<<"No"<<endl;
			continue;
		}
		if(ds[a]<ds[b]&&(a==s||b==g||uf.same(a,b))&&sorrev[a]<sorrev[b])cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}
accuracy: 0.8888888888888888
time_ms: 150
memory_kb: 19692
final_rank: 9

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#line 2 "/home/kotatsugame/library/datastructure/UF.cpp"
struct UF{
	int n;
	vector<int>parent,rank;
	UF(int n_=0):n(n_),parent(n_),rank(n_,1)
	{
		for(int i=0;i<n_;i++)parent[i]=i;
	}
	int find(int a){return parent[a]!=a?parent[a]=find(parent[a]):a;}
	bool same(int a,int b){return find(a)==find(b);}
	bool unite(int a,int b)
	{
		a=find(a),b=find(b);
		if(a==b)return false;
		if(rank[a]<rank[b])
		{
			parent[a]=b;
			rank[b]+=rank[a];
		}
		else
		{
			parent[b]=a;
			rank[a]+=rank[b];
		}
		return true;
	}
	int size(int a){return rank[find(a)];}
};
#line 6 "a.cpp"
int N,M,s,g,Q;
vector<pair<int,int> >G[1<<17];
vector<int>dist(int st)
{
	vector<int>ret(N,1e9);
	ret[st]=0;
	priority_queue<pair<int,int> >P;
	P.push(make_pair(0,st));
	while(!P.empty())
	{
		int cost=-P.top().first,u=P.top().second;
		P.pop();
		if(ret[u]<cost)continue;
		for(pair<int,int>e:G[u])
		{
			int v=e.first,nxt=cost+e.second;
			if(ret[v]>nxt)
			{
				ret[v]=nxt;
				P.push(make_pair(-nxt,v));
			}
		}
	}
	return ret;
}
main()
{
	cin>>N>>M;
	for(int i=0;i<M;i++)
	{
		int a,b,c;cin>>a>>b>>c;
		a--,b--;
		G[a].push_back(make_pair(b,c));
		G[b].push_back(make_pair(a,c));
	}
	cin>>s>>g>>Q;
	s--,g--;
	vector<int>ds=dist(s),dg=dist(g);
	vector<vector<int> >H(N);
	vector<int>indeg(N);
	UF uf(N);
	for(int i=0;i<N;i++)for(pair<int,int>e:G[i])
	{
		int u=i,v=e.first;
		if(ds[u]+e.second+dg[v]==ds[g])
		{
			H[u].push_back(v);
			indeg[v]++;
			if(u!=s&&v!=g)uf.unite(u,v);
		}
	}
	queue<int>P;
	for(int i=0;i<N;i++)if(!indeg[i])P.push(i);
	vector<int>sor;
	vector<int>sorrev(N,1e9);
	while(!P.empty())
	{
		int u=P.front();P.pop();
		sorrev[u]=sor.size();
		sor.push_back(u);
		for(int v:H[u])if(!--indeg[v])
		{
			P.push(v);
		}
	}
	for(;Q--;)
	{
		int a,b;cin>>a>>b;a--,b--;
		if(ds[a]+dg[a]!=ds[g]||ds[b]+dg[b]!=ds[g])
		{
			cout<<"No"<<endl;
			continue;
		}
		if(ds[a]<ds[b]&&(a==s||b==g||uf.same(a,b))&&sorrev[a]<sorrev[b])cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}
accuracy: 0.6666666666666666
time_ms: 120
memory_kb: 15464
final_rank: 10

code_snippet: #line 1 "a.cpp"
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#line 2 "/home/kotatsugame/library/datastructure/UF.cpp"
struct UF{
	int n;
	vector<int>parent,rank;
	UF(int n_=0):n(n_),parent(n_),rank(n_,1)
	{
		for(int i=0;i<n_;i++)parent[i]=i;
	}
	int find(int a){return parent[a]!=a?parent[a]=find(parent[a]):a;}
	bool same(int a,int b){return find(a)==find(b);}
	bool unite(int a,int b)
	{
		a=find(a),b=find(b);
		if(a==b)return false;
		if(rank[a]<rank[b])
		{
			parent[a]=b;
			rank[b]+=rank[a];
		}
		else
		{
			parent[b]=a;
			rank[a]+=rank[b];
		}
		return true;
	}
	int size(int a){return rank[find(a)];}
};
#line 6 "a.cpp"
int N,M,s,g,Q;
vector<pair<int,int> >G[1<<17];
vector<int>dist(int st)
{
	vector<int>ret(N,1e9);
	ret[st]=0;
	priority_queue<pair<int,int> >P;
	P.push(make_pair(0,st));
	while(!P.empty())
	{
		int cost=-P.top().first,u=P.top().second;
		P.pop();
		if(ret[u]<cost)continue;
		for(pair<int,int>e:G[u])
		{
			int v=e.first,nxt=cost+e.second;
			if(ret[v]>nxt)
			{
				ret[v]=nxt;
				P.push(make_pair(-nxt,v));
			}
		}
	}
	return ret;
}
main()
{
	cin>>N>>M;
	for(int i=0;i<M;i++)
	{
		int a,b,c;cin>>a>>b>>c;
		a--,b--;
		G[a].push_back(make_pair(b,c));
		G[b].push_back(make_pair(a,c));
	}
	cin>>s>>g>>Q;
	s--,g--;
	vector<int>ds=dist(s),dg=dist(g);
	vector<vector<int> >H(N);
	vector<int>indeg(N);
	UF uf(N);
	for(int i=0;i<N;i++)for(pair<int,int>e:G[i])
	{
		int u=i,v=e.first;
		if(ds[u]+e.second+dg[v]==ds[g])
		{
			H[u].push_back(v);
			indeg[v]++;
			if(u!=s&&v!=g)uf.unite(u,v);
		}
	}
	queue<int>P;
	for(int i=0;i<N;i++)if(!indeg[i])P.push(i);
	vector<int>sor;
	vector<int>sorrev(N);
	while(!P.empty())
	{
		int u=P.front();P.pop();
		sorrev[u]=sor.size();
		sor.push_back(u);
		for(int v:H[u])if(!--indeg[v])
		{
			P.push(v);
		}
	}
	for(;Q--;)
	{
		int a,b;cin>>a>>b;a--,b--;
		if(ds[a]+dg[a]!=ds[g]||ds[b]+dg[b]!=ds[g])
		{
			cout<<"No"<<endl;
			continue;
		}
		if((a==s||b==g||uf.same(a,b))&&sorrev[a]<sorrev[b])cout<<"Yes"<<endl;
		else cout<<"No"<<endl;
	}
}
accuracy: 0.5555555555555556
time_ms: 120
memory_kb: 15372
final_rank: 19

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define int long long
#define V vector
#define vel V<int> 
#define vvel V<V<int>>
#define pin pair<int,int>
#define rep(i,n) for(int i=0;i<n;i++)
#define sor(v) sort(v.begin(),v.end())
#define mkp make_pair
#define mmax(a,b) a=max(a,b)
#define lowerbound(v,val) lower_bound(v.begin(),v.end(),val)
vel dijk(V<V<pin>> &way, int st, int inf) {
	int n = way.size();
	vel dist(n, inf);
	priority_queue<pin, vector<pin>, greater<pin>> pq;
	pq.push(mkp(0, st));
	while (!pq.empty()) {
		pin x = pq.top(); pq.pop();
		int dip = x.first;
		int pot = x.second;
		if (dist[pot] == inf) { 
			dist[pot] = dip; 
			for (auto y : way[pot]) {
				int nex = y.first;
				int dxy = y.second;
				pq.push(mkp(dip + dxy, nex));
			}
		}
	}
	return dist;
}
signed main() {
	int n, m; cin >> n >> m;
	V<V<pin>> way(n);
	rep(i, m) {
		int u, v, w; cin >> u >> v >> w;
		u--; v--;
		way[u].push_back(mkp(v, w));
		way[v].push_back(mkp(u, w));
	}
	int a, b; cin >> a >> b; a--; b--;
	int inf = ((long long)10000) * (n + m + 1);
	vel da = dijk(way, a, inf);
	vel db = dijk(way, b, inf);
	int dab = da[b];
	vvel invway(n);
	rep(i, n) {
		for (pin x : way[i]) {
			int nex = x.first;
			int dix = x.second;
			if (da[i] + dix + db[nex] == dab) {
				invway[nex].push_back(i);
			}
		}
	}
	V<pin> qdb(n);
	rep(i, n) {qdb[i] = mkp(db[i],i);}
	sor(qdb);
	vel ord(n);
	rep(i, n) { ord[i] = qdb[i].second; }
	int q; cin >> q;
	V<pin> que;
	vel rui(60, 1);
	rep(i, 59) { rui[i + 1] = rui[i] * (long long)2; }
	rep(_, q) {
		int c, d; cin >> c >> d; c--; d--;
		que.push_back(mkp(c, d));
		if ((que.size() == 60) || (_ == q - 1)) {
			vel dp(n);
			int sz = que.size();
			rep(i, sz) {
				int d = que[i].second;
				dp[d] +=rui[i];
			}
			rep(i, n) {
				int pot = ord[i];
				for (int nex : invway[pot]) {
					dp[nex] |= dp[pot];
				}
			}
			rep(i, sz) {
				int c = que[i].first;
				if ( (dp[c] & rui[i]) != 0) {
					cout << "Yes" << endl;
				}
				else { cout << "No" << endl; }
			}
			que = {};
		}
	}
	return 0;
}
accuracy: 1
time_ms: 450
memory_kb: 24320
final_rank: 2

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define int long long
#define V vector
#define vel V<int> 
#define vvel V<V<int>>
#define pin pair<int,int>
#define rep(i,n) for(int i=0;i<n;i++)
#define sor(v) sort(v.begin(),v.end())
#define mkp make_pair
#define mmax(a,b) a=max(a,b)
#define lowerbound(v,val) lower_bound(v.begin(),v.end(),val)
vel dijk(V<V<pin>> &way, int st, int inf) {
	int n = way.size();
	vel dist(n, inf);
	priority_queue<pin, vector<pin>, greater<pin>> pq;
	pq.push(mkp(0, st));
	while (!pq.empty()) {
		pin x = pq.top(); pq.pop();
		int dip = x.first;
		int pot = x.second;
		if (dist[pot] == inf) { 
			dist[pot] = dip; 
			for (auto y : way[pot]) {
				int nex = y.first;
				int dxy = y.second;
				pq.push(mkp(dip + dxy, nex));
			}
		}
	}
	return dist;
}
signed main() {
	int n, m; cin >> n >> m;
	V<V<pin>> way(n);
	rep(i, m) {
		int u, v, w; cin >> u >> v >> w;
		u--; v--;
		way[u].push_back(mkp(v, w));
		way[v].push_back(mkp(u, w));
	}
	int a, b; cin >> a >> b; a--; b--;
	int inf = ((long long)10000) * (n + m + 1);
	vel da = dijk(way, a, inf);
	vel db = dijk(way, b, inf);
	int dab = da[b];
	vvel invway(n);
	rep(i, n) {
		for (pin x : way[i]) {
			int nex = x.first;
			int dix = x.second;
			if (da[i] + dix + db[nex] == dab) {
				invway[nex].push_back(i);
			}
		}
	}
	V<pin> qdb(n);
	rep(i, n) {qdb[i] = mkp(db[i],i);}
	sor(qdb);
	vel ord(n);
	rep(i, n) { ord[i] = qdb[i].second; }
	int q; cin >> q;
	V<pin> que;
	rep(_, q) {
		int c, d; cin >> c >> d; c--; d--;
		que.push_back(mkp(c, d));
		if ((que.size() == 60) || (_ == q - 1)) {
			vel dp(n);
			int sz = que.size();
			rep(i, sz) {
				int d = que[i].second;
				dp[d] += (1 << i);
			}
			rep(i, n) {
				int pot = ord[i];
				for (int nex : invway[pot]) {
					dp[nex] |= dp[pot];
				}
			}
			rep(i, sz) {
				int c = que[i].first;
				if ( (dp[c] & (1 << i)) != 0) {
					cout << "Yes" << endl;
				}
				else { cout << "No" << endl; }
			}
			que = {};
		}
	}
	return 0;
}
accuracy: 0.3333333333333333
time_ms: 200
memory_kb: 18468
final_rank: 20