#include <iostream>
#include <complex>
#include <sstream>
#include <string>
#include <algorithm>
#include <deque>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <vector>
#include <set>
#include <limits>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <ctime>
using namespace std;
#define REP(i, j) for(int i = 0; i < (int)(j); ++i)
#define FOR(i, j, k) for(int i = (int)(j); i < (int)(k); ++i)
#define SORT(v) sort((v).begin(), (v).end())
#define REVERSE(v) reverse((v).begin(), (v).end())
typedef complex<double> P;

void dfs(int v, int *used, vector< vector<int> > &G, vector<int> &vs){
  used[v] = true;
  REP(i, G[v].size()){
    int next = G[v][i];
    if(!used[next]) dfs(next, used, G, vs);
  }
  vs.push_back(v);
}

void rdfs(int v, int cnt, int *used, vector<int> &cmp, vector< vector<int> > &G){
  used[v] = true;
  cmp[v] = cnt;
  REP(i, G[v].size()){
    int next = G[v][i];
    if(!used[next]) rdfs(next, cnt, used, cmp, G);
  }
}

vector<int> scc(int V, vector< vector<int> > &G, vector< vector<int> > &RG){
  int used[V];
  memset(used, 0, sizeof(used));
  vector<int> vs, cmp(V);
  REP(i, V) if(!used[i]) dfs(i, used, G, vs);
  memset(used, 0, sizeof(used));
  int cnt = 0;
  REVERSE(vs);
  REP(i, vs.size()) if(!used[vs[i]]) rdfs(vs[i], cnt++, used, cmp, RG);
  return cmp;
}

int main() {
  int V, E; cin >>V >>E;
  vector< vector<int> > G(V), RG(V);
  REP(i, E){
    int f, t; cin >>f >>t;
    G[f].push_back(t);
    RG[t].push_back(f);
  }
  vector<int> cmp = scc(V, G, RG);
  int Q; cin >>Q;
  REP(q, Q){
    int a, b; cin >>a >>b;
    cout <<(cmp[a] == cmp[b]) <<endl;
  }
  return 0;
}