#include <stdio.h>
#include <algorithm>
#include <utility>
#include <functional>
#include <cstring>
#include <queue>
#include <stack>
#include <cmath>
#include <iterator>
#include <vector>
#include <string>
#include <set>
#include <iostream>
#include <random>
#include <map>
#include <iomanip>
#include <stdlib.h>
#include <list>
#include <typeinfo>
#include <list>
#include <set>
#include <cassert>
#include <fstream>
#include <unordered_map>
#include <cstdlib>
#include <complex>
#include <cctype>
#include <bitset>
using namespace std;

using ll = long long;
using vll = vector<ll>;
using pll = pair<ll, ll>;
using qll = queue<ll>;
using vb = vector<bool>;
using mll = map<ll, ll>;
using sll = stack<ll>;
#define REP(i,n) for(ll i(0);(i)<(n);(i)++)
#define rep(i,n) for(ll i(0);(i)<(n);(i)++)
#define ALL(a) a.begin(), a.end()
#define enld endl //* missspell check
const ll INF = 1LL << 60;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a = b; return 1; } return 0; }

struct SCC{
    vector<vll> G, revG; 
    vll postOrder; //* record post-order of dfs on G
    vll checked; 
    vll component;
    vector<set<ll> > reducedG;
    vll numVertex;
    ll num_component = -1;

    SCC(ll N){ 
        G.resize(N); revG.resize(N); 
        checked.resize(N, 0); component.resize(N);
    }
    void add_edge(ll a, ll b) { G[a].push_back(b); revG[b].push_back(a); }
    //* first round of dfs on G
    void dfs(ll v) {
        checked[v] = 1;
        for(auto u: G[v]) if(!checked[u]) dfs(u);
        postOrder.push_back(v);
    }
    //* second round dfs on revG
    //* k for recording strongly connected components id
    void rev_dfs(ll v, ll k){ 
        checked[v] = 1;
        component[v] = k;
        for(auto u: revG[v]){
            if(!checked[u]) rev_dfs(u, k);
        }
    }
    ll calculate_component(){
        //* 1. dfs on G
        fill(ALL(checked), 0);
        postOrder.clear();
        REP(v, G.size()){
            if(!checked[v]) dfs(v);
        }
        //* 2. dfs on revG
        fill(ALL(checked), 0);
        ll k = 0;
        for(ll i = postOrder.size() - 1; i >= 0; i--){
            if(!checked[postOrder[i]]) rev_dfs(postOrder[i], k++);
        }
        //* 3. get number of vectexes in each components
        numVertex.resize(k, 0);
        for(ll v = 0; v < G.size(); v++)  numVertex[component[v]]++;
        
        num_component = k;
        return k;
    }
    bool is_same(ll u, ll v){ return (component[u] == component[v]); }

    void reduce(){
        ll num_comp = calculate_component();
        reducedG.resize(num_comp);
        for(ll u = 0; u < G.size(); u++){
            for(ll v: G[u]){
                if(component[u] == component[v]) continue;
                reducedG[component[u]].insert(component[v]);
            }
        }
    }

    vector<vll> get_reduce_graph(){
        vector<vll> Gout(num_component);
        for(ll i = 0; i < num_component; i++){
            Gout[i] = vll(ALL(reducedG[i]));
        }
        return Gout;
    }
};


//* submited to: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_C
int main(){
    ll N, M; cin >> N >> M;
    SCC scc_obj(N);
    REP(_, M){
        ll u, v; cin >> u >> v;
        scc_obj.add_edge(u, v);
    }
    ll num_cmp = scc_obj.calculate_component();
    ll Q; cin >> Q;
    REP(q, Q){
        ll u, v; cin >> u >> v;
        if(scc_obj.is_same(u, v)) cout << 1 << endl;
        else cout << 0 << endl;
    }
    return 0;
}



Measured memory_bytes: 4720