import std.algorithm;
import std.array;
import std.ascii;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void log(A...)(A arg) {
    stderr.writeln(arg);
}
int size(T)(in T s) {
    return cast(int)s.length;
}

class Graph {
    int V;
    int[][] g, rg;
    this(int V) {
        g = new int[][V];
        rg = new int[][V];
        this.V = V;
    }
    void addEdge(int from, int to) {
        g[from] ~= to;
        rg[to] ~= from;
    }
    /* ???????£°?????????????????????????????§?????§??????????¬?????????????????????? */
    int[] scc() {
        auto used = new bool[V];
        int[] vs;
        void dfs1(int v) {
            used[v] = true;
            foreach (u; g[v]) {
                if (used[u]) continue;
                dfs1(u);
            }
            vs ~= v;
        }
        void dfs2(int v, int k, int[] order) {
            used[v] = true;
            order[v] = k;
            foreach (u; rg[v]) {
                if (used[u]) continue;
                dfs2(u, k, order);
            }
        }
        foreach (v; 0 .. V) {
            if (used[v]) continue;
            dfs1(v);
        }
        used[] = false;
        int k = 0;
        auto ord = new int[V]; ord[] = -1;
        foreach_reverse (v; vs) {
            if (used[v]) continue;
            dfs2(v, k++, ord);
        }
        return ord;
    }
}

void main() {
    int V, E; readf("%d %d\n", &V, &E);
    auto g = new Graph(V);
    foreach (i; 0 .. E) {
        int s, t; readf("%d %d\n", &s, &t);
        g.addEdge(s, t);
    }
    auto ord = g.scc();
    int Q; readf("%d\n", &Q);
    foreach (_; 0 .. Q) {
        int u, v; readf("%d %d\n", &u, &v);
        writeln(cast(int)(ord[u] == ord[v]));
    }
}