#include <iostream>
#include <vector>
#include <cstring>
#include <utility>
#include <map>
#include <array>
using namespace std;

using Weight = int;

// ??????????????????
struct Edge {
    int from, to;
    Weight weight;

    Edge() {}
    Edge(int to) : from(-1), to(to), weight(-1) {}
    Edge(int from, int to) : from(from), to(to), weight(-1) {}
    Edge(int from, int to, Weight weight) : from(from), to(to), weight(weight) {}

    bool operator<(const Edge& e) const {
        return (weight != e.weight) ? (weight < e.weight) : (from < e.from);
    }
    bool operator>(const Edge& e) const {
        return (weight != e.weight) ? (weight > e.weight) : (from > e.from);
    }
};

using Arc = Edge;
using Graph = vector<vector<Edge>>;
using DGraph = vector<vector<Arc>>;

// Kosaraju's algorithm
// [TODO] compose_dgraph??????????????°??????????????????????????????
namespace SCC {
    const int MAX_V = 10010;

    DGraph dgraph, rev_dgraph, new_dgraph;

    array<bool, MAX_V> used;
    array<int, MAX_V> new_id; // ????????????????????????????????£?????????????§£???????????????????????????

    vector<int> po_nodes;   // ??°????????????(postorder)??????????????????

    DGraph& kosaraju(DGraph&);
    void dfs(int);
    void rev_dfs(int, int);
    DGraph& compose_dgraph(int);

    DGraph& kosaraju(DGraph& dg) {
        used.fill(false);
        po_nodes.clear();

        dgraph = dg;
        rev_dgraph = DGraph(dg.size());

        // ????????????????????°??????????§????
        for (int v = 0; v < dgraph.size(); v++) {
            for (Edge e : dgraph[v]) {
                rev_dgraph[e.to].push_back(Edge(v));
            }
        }

        // ??°????????????????????????????????????
        for (int v = 0; v < dgraph.size(); v++) {
            if (!used[v]) {
                dfs(v);
            }
        }

        used.fill(false);

        int num = 0;    // ?????£?????????????????°
        for (int i = po_nodes.size() - 1; i >= 0; i--) {
            int v = po_nodes[i];
            if (!used[v]) {
                rev_dfs(v, num);
                num++;
            }
        }

        return compose_dgraph(num);
    }

    void dfs(int v) {
        used[v] = true;
        for (Edge e : dgraph[v]) {
            if (!used[e.to]) {
                dfs(e.to);
            }
        }
        po_nodes.push_back(v);
    }

    void rev_dfs(int v, int id) {
        used[v] = true;
        new_id[v] = id;
        for (Edge e : rev_dgraph[v]) {
            if (!used[e.to]) {
                rev_dfs(e.to, id);
            }
        }
    }

    // ?????????kosaraju????????¶?????¨!!
    DGraph& compose_dgraph(int num) {
        new_dgraph = DGraph(num);
        using P = pair<int, int>;

        map<P, int> map;

        for (int v = 0; v < dgraph.size(); v++) {
            int from_id = new_id[v];
            for (Edge e : dgraph[v]) {
                int to_id = new_id[e.to];

                // ???????????????????????¶
                if (from_id != to_id && map.count(P(from_id, to_id)) == 0) {
                    map[P(from_id, to_id)] = true;
                    new_dgraph[from_id].push_back(Edge(to_id));
                }
            }
        }
        return new_dgraph;
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int v, e;
    cin >> v >> e;

    DGraph dgraph(v);

    for (int i = 0; i < e; i++) {
        int s, t;
        cin >> s >> t;
        dgraph[s].push_back(Edge(t));
    }

    auto new_graph = SCC::kosaraju(dgraph);

    int q;
    cin >> q;
    for (int i = 0; i < q; i++) {
        int u, v;
        cin >> u >> v;
        if (SCC::new_id[u] == SCC::new_id[v]) cout << 1 << endl;
        else cout << 0 << endl;
    }

    return 0;
}

Measured memory_bytes: 5500