#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < int(n); i++)
#define rep1(i,n) for (int i = 1; i <= int(n); i++)
#define repR(i,n) for (int i = int(n)-1; i >= 0; i--)
#define rep1R(i,n) for (int i = int(n); i >= 1; i--)
#define loop(i,a,B) for (int i = a; i B; i++)
#define loopR(i,a,B) for (int i = a; i B; i--)
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fst first
#define snd second
#define cauto const auto
#ifdef LOCAL
#define dump(...) cerr << "[" << __LINE__ << ":" << __FUNCTION__ << "] ", my_dmp(#__VA_ARGS__, __VA_ARGS__)
void my_dmp(const char*) { cerr << endl; }
template <class T, class... U>
void my_dmp(const char *s, T const& x, U const& ...y) { const char *o = "({[", *e = "]})"; for (int i = 0; *s != '\0'; cerr << *s++) { if (count(o,o+3,*s)) i++; if (count(e,e+3,*s)) i--; if (!i && *s == ',') break; } cerr << " = " << x; if (*s == ',') cerr << ", ", s++; my_dmp(s, y...); }
#else
#define dump(...)
#endif
using ll = long long;
#define int ll
template <class T> using pque_max = priority_queue<T>;
template <class T> using pque_min = priority_queue<T, vector<T>, greater<T> >;
template <class T, class = typename T::iterator, class = typename enable_if<!is_same<T, string>::value>::type>
ostream& operator<<(ostream& os, T const& v) { os << "{"; for (auto const& x : v) os << " " << x; return os << " }"; }
template <class T> istream& operator>>(istream& is, vector<T>& v) { for (auto& x : v) is >> x; return is; }
template <class T, class S> ostream& operator<<(ostream& os, pair<T,S> const& p) { return os << "(" << p.first << ", " << p.second << ")"; }
template <class T, class S> istream& operator>>(istream& is, pair<T,S>& p) { return is >> p.first >> p.second; }
struct my_Init { my_Init() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); } } my_init;

template <class T> void quit(T const& x) { cout << x << endl; exit(0); }
template <class T> bool chmin(T& x, T const& y) { if (x > y) { x = y; return true; } return false; }
template <class T> bool chmax(T& x, T const& y) { if (x < y) { x = y; return true; } return false; }
template <class It> auto sumof(It b, It e) { return accumulate(b,e,typename iterator_traits<It>::value_type{}); }
////////////////////////////////
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_C&lang=ja

template <class E>
pair<vector<vector<int>>, vector<int>> scc(vector<vector<E>> const& g) {
  const int n = g.size();
  vector<int> ord(n), low(n), s; s.reserve(n);
  vector<vector<int> > grp; grp.reserve(n); // needed??
  int time = 0;
  const function<void(int)> dfs = [&](int v) {
      low[v] = ord[v] = ++time;
      s.push_back(v);
      for (auto const& e : g[v]) {
          if (ord[e] == 0) {
              dfs(e);
              chmin(low[v], low[e]);
          } else if (ord[e] > 0) {
              chmin(low[v], ord[e]);
          }
      }          
      if (low[v] == ord[v]) {
          auto it = s.end();
          do ord[*--it] = -1; while (*it != v);
          grp.emplace_back(s.end()-it);
          copy(it, s.end(), grp.back().begin());
          s.erase(it, s.end());
      }
  };
  rep (v,n) if (ord[v] == 0) dfs(v);
  reverse(grp.begin(), grp.end());
  rep (i,grp.size()) for (int v : grp[i]) ord[v] = i;
  return { grp, ord };
}

template <class E>
pair<vector<vector<int>>, vector<int>> scc2(vector<vector<E>> const& g) {
    const int n = g.size();
    vector<vector<int> > rg(n), grp; grp.reserve(n); // needed??
    vector<int> id(n), order; order.reserve(n);
    rep (i,g.size()) for (auto const& e : g[i]) rg[e].push_back(i);
    const function<void(int)> dfs = [&](int v) {
        if (id[v]) return;
        id[v] = -1;
        for (auto const& e : g[v]) dfs(e);
        order.push_back(v);
    };
    const function<void(int,int)> rdfs = [&](int v, int k) {
        if (id[v] != -1) return;
        id[v] = k;
        for (int to : rg[v]) rdfs(to, k);
    };
    rep (i,n) dfs(i);
    reverse(order.begin(), order.end());
    int k = 0;
    for (int v : order) rdfs(v,k++);
    grp.resize(k);
    rep (i,n) grp[id[i]].push_back(i);
    return { grp, id };
}


int32_t main() {
    int n,m; cin >> n >> m;
    vector<vector<int> > g(n);
    rep (i,m) {
        int s,t; cin >> s >> t;
        g[s].push_back(t);
    }

    auto id = scc2(g).snd;

    int q; cin >> q;
    while (q--) {
        int u,v; cin >> u >> v;
        cout << (id[u]==id[v]) << "\n";
    }
}



Measured memory_bytes: 5500