#include<bits/stdc++.h>
using namespace std;

struct Edge {int from, to, weight;};
struct Query {int from, to;};

vector<int> Dijkstra(const vector<vector<Edge>>& edge, const int start, const int goal) {
    typedef tuple<int, int> Node;
    const int INF = INT_MAX >> 1;

    vector<int> cost(edge.size(), INF);
    priority_queue<Node, vector<Node>, greater<Node>> q;
    q.emplace(0, start);
    while(!q.empty()) {
        int c, v;
        tie(c, v) = q.top();
        q.pop();
        if(cost[v] != INF) continue;
        cost[v] = c;
        if(v == goal) break;
        for(const auto& e: edge[v]) if(cost[e.to] == INF) q.emplace(c + e.weight, e.to);
    }
    return cost;
}

vector<vector<int>> optimize(const vector<vector<Edge>>& edge, const vector<int>& cost, const int start, const int goal) {
    vector<vector<int>> outedge(edge.size());
    vector<vector<int>> inedge(edge.size());
    for(const auto& list: edge) for(const auto& e: list) {
        if(cost[e.from] + e.weight > cost[e.to]) continue;
        outedge[e.from].push_back(e.to);
        inedge[e.to].push_back(e.from);
    }

    typedef tuple<int, int> Node;
    priority_queue<Node, vector<Node>, greater<Node>> q;
    for(int v = 0; v < edge.size(); ++v) q.emplace(outedge[v].size(), v);
    vector<bool> visited(edge.size(), false);
    while(!q.empty()) {
        int outdegree, v;
        tie(outdegree, v) = q.top();
        q.pop();
        if(outdegree) break;
        if(visited[v]) continue;
        visited[v] = true;
        if(v == start || v == goal) continue;
        for(const auto& i: inedge[v]) {
            outedge[i].erase(find(outedge[i].begin(), outedge[i].end(), v));    // → ここではフラグだけ付けておいて、後で構築しなおしたほうが早いかもしれない
            q.emplace(outedge[i].size(), i);
        }
    }
    return outedge;
}

void dfs(const vector<vector<int>>& edge, const int v, vector<bool>& visited, vector<int>& order) {
    if(visited[v]) return;
    visited[v] = true;
    for(const auto& to: edge[v]) dfs(edge, to, visited, order);
    order.push_back(v);
}

vector<int> topological_sort(const vector<vector<int>>& edge, const int start, const int goal) {
    vector<int> order;
    vector<bool>visited(edge.size(), false);
    dfs(edge, start, visited, order);
    reverse(order.begin(), order.end());
    return order;
}

int main() {
    int S, R;
    cin >> S >> R;

    vector<vector<Edge>> edge(S);
    for(int i = 0; i < R; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        --u; --v;
        edge[u].push_back({u, v, w});
        edge[v].push_back({v, u, w});
    }

    int a, b;
    cin >> a >> b;
    --a; --b;

    int Q;
    cin >> Q;
    vector<Query> query;
    for(int i = 0; i < Q; ++i) {
        int c, d;
        cin >> c >> d;
        query.push_back({--c, --d});
    }

    auto cost = Dijkstra(edge, a, b);
    auto optimized_edge = optimize(edge, cost, a, b);
    auto order = topological_sort(optimized_edge, a, b);

    const int BIT = 64;
    for(int i = 0; i < Q; i += BIT) {
        vector<bitset<BIT>> dp(S);
        for(int j = 0; j < BIT && i + j < Q; ++j) dp[query[i + j].from].set(j);
        for(const auto& from: order) for(const auto& to: optimized_edge[from]) dp[to] = dp[to] | dp[from];
        for(int j = 0; j < BIT && i + j < Q; ++j) cout << (dp[query[i + j].to].test(j) ? "Yes" : "No") << endl;
    }
}

Measured memory_bytes: 27196