#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
using namespace std;
#define REP(i,n) for (int i=0;i<(n);++i)
#define rep(i,a,b) for(int i=a;i<(b);++i)
constexpr int INF = 1 << 30;
constexpr int MOD = 1e9 + 7;

struct Edge {
  int src, dst, cost;
  Edge(int s, int d, int c = 1) : src(s), dst(d), cost(c) {}
  bool operator<(const Edge &e){ return cost < e.cost;}
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

class SCC {
  public:
  SCC(int n, Graph g) : n(n), g(g), used(n, -1), components(n) {
    rg.resize(n);
    for(int i = 0; i < n; ++i)
      for(Edge e : g[i])
        rg[e.dst].emplace_back(e.dst, e.src, e.cost);

    for(int i = 0; i < n; ++i) if(used[i] == -1) dfs1(i);
    for(int i = (int)order.size() - 1; i >= 0; --i) if(!used[order[i]]) dfs2(order[i], k++);
  }
  int size() { return k; }
  bool same(int x, int y) { return components[x] == components[y]; }

  private:
  int n, k;
  vector<int> used, order, components;
  Graph g, rg;

  void dfs1(int v) { used[v] = 0; for(Edge e : g[v]) if(!!used[e.dst]) dfs1(e.dst); order.push_back(v); }
  void dfs2(int v, int k) { used[v] = 1; components[v] = k; for(Edge e : rg[v]) if(!used[e.dst]) dfs2(e.dst, k); }

};

int main() {
  cin.tie(0); ios_base::sync_with_stdio(false);
  int V, E, x, y, q; cin >> V >> E;

  Graph g(V);
  REP(i, E) {
    cin >> x >> y;
    g[x].emplace_back(x, y);
  }
  SCC scc(V, g);

  cin >> q;
  REP(i, q) {
    cin >> x >> y;
    cout << scc.same(x, y) << '\n';
  }
  return 0;
}
