#include <cstdio>
#include <vector>
#include <algorithm>
#include <stack>
#include <functional>

//#ifdef NO_UNLOCK_IO
#define getchar_unlocked getchar
#define putchar_unlocked putchar
//#endif

struct FastIO {
    static void scan(double &x) {
        scanf("%lf", &x);
    }
    template <class Integral>
    static void scan(Integral &x) {
        int k, m=0;
        x = 0;
        for (;;) {
            k = getchar_unlocked();
            if (k == '-') {
                m = 1;
                break;
            } else if ('0' <= k && k <= '9') {
                x = k-'0';
                break;
            }
        }
        for (;;) {
            k = getchar_unlocked();
            if (k < '0' || k > '9')
                break;

            x = x*10 + k-'0';
        }

        if (m)
            x = -x;
    }
    template <class Arithmetic, class... Rest>
    static void scan(Arithmetic &x, Rest&... y) {
        scan(x);
        scan(y...);
    }
    static void print(double x, char c) {
        printf("%.12f%c", x, c);
    }
    template <class Integral>
    static void print(Integral x, char c) {
        int s=0, m=0;
        char f[20];
        if (x < 0) {
            m = 1;
            x = -x;
        }
        while (x) {
            f[s++] = x%10;
            x /= 10;
        }

        if (!s)
            f[s++] = 0;

        if (m) putchar_unlocked('-');
        while (s--)
            putchar_unlocked(f[s]+'0');

        putchar_unlocked(c);
    }
    template <class Arithmetic>
    static void println(Arithmetic x) {
        print(x, '\n');
    }
};

template <class Weight>
struct Edge {
    const size_t src, dst;
    const Weight cost;
    Edge(size_t src, size_t dst, Weight cost):
        src(src), dst(dst), cost(cost)
    {}
};

template <class Weight>
bool operator <(const Edge<Weight> &e, const Edge<Weight> &f) {
    if (e.cost != f.cost) {
        return e.cost > f.cost;
    } else {
        return (e.src != f.src)? (e.src < f.src) : (e.dst < f.dst);
    }
}

template <class Weight>
using Edges=std::vector<Edge<Weight>>;
template <class Weight>
using Vertex=std::vector<Edge<Weight>>;

template <class Weight>
struct Graph: std::vector<Vertex<Weight>> {
    static constexpr Weight INF=std::numeric_limits<Weight>::max()/4;
    Graph(): std::vector<Vertex<Weight>>() {}
    Graph(size_t v): std::vector<Vertex<Weight>>(v) {}
    void connect_u(size_t s, size_t d, Weight c=1) {
        (*this)[s].emplace_back(s, d, c);
        (*this)[d].emplace_back(d, s, c);
    }
    void connect_d(size_t s, size_t d, Weight c=1) {
        (*this)[s].emplace_back(s, d, c);
    }
};

template <class Weight>
std::vector<size_t> scc(const Graph<Weight> &g, Graph<Weight> *dag=nullptr) {
    // Returns the mapping: to which scc the vertex belongs
    const size_t v=g.size();
    std::vector<size_t> ord(v), low(v), index(v);
    std::stack<size_t> s;
    std::vector<bool> staying(v);
    size_t t=0, numcmp=0;

    std::function<void (size_t)> visit=[&](size_t v)->void {
        low[v] = ord[v] = ++t;
        s.emplace(v);
        staying[v] = true;

        for (const auto &e: g[v]) {
            size_t w=e.dst;
            if (ord[w] == 0) {
                // not visited yet
                visit(w);
                if (low[v] > low[w])
                    low[v] = low[w];
            } else if (staying[w]) {
                // second (or more) visit
                if (low[v] > ord[w])
                    low[v] = ord[w];
            }
        }

        if (low[v] == ord[v]) {
            size_t w;
            do {
                w = s.top();
                s.pop();
                staying[w] = false;
                index[w] = numcmp;
            } while (v != w);
            ++numcmp;
        }
    };

    for (size_t u=0; u<v; ++u)
        if (ord[u] == 0)
            visit(u);

    /* the size of each of components */
    // std::vector<int> cmp_size(numcmp);
    // for (int i: index)
    //    ++cmp_size[i];

    if (!dag)
        return index;

    dag->resize(numcmp);
    for (const auto &v: g)
        for (const auto &e: v)
            if (index[e.src] != index[e.dst])
                dag->connect_d(index[e.src], index[e.dst], e.cost);

    return index;
}

int main() {
    int v, e;
    FastIO::scan(v, e);

    Graph<int> g(v);
    for (int i=0; i<e; ++i) {
        int s, t;
        FastIO::scan(s, t);

        g.connect_d(s, t);
    }

    std::vector<size_t> cmp=scc(g);

    int q;
    FastIO::scan(q);

    for (int i=0; i<q; ++i) {
        int u, v;
        FastIO::scan(u, v);

        FastIO::println(cmp[u]==cmp[v]? 1:0);
    }
    return 0;
}

Measured memory_bytes: 4176