#define _CRT_SECURE_NO_WARNINGS
#include "bits/stdc++.h"

#define PB push_back
#define PF push_front
#define LB lower_bound
#define UB upper_bound
#define fr(x) freopen(x,"r",stdin)
#define fw(x) freopen(x,"w",stdout)
#define iout(x) printf("%d\n",x)
#define lout(x) printf("%lld\n",x)
#define REP(x,l,u) for(ll x = l;x<u;x++)
#define RREP(x,l,u) for(ll x = l;x>=u;x--)
#define complete_unique(a) a.erase(unique(a.begin(),a.end()),a.end())
#define mst(x,a) memset(x,a,sizeof(x))
#define all(a) a.begin(),a.end()
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define MP make_pair
#define sqr(x) ((x)*(x))
#define lowbit(x) ((x)&(-(x)))
#define lson (ind<<1)
#define rson (ind<<1|1)
#define se second
#define fi first
#define sz(x) ((int)x.size())
#define EX0 exit(0);

typedef  long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ld;
using namespace std;
typedef vector<ll> VLL;
typedef vector<int> VI;
const int block_size = 320;
typedef complex<ll> point;
const ll mod = 1e9 + 7;
const ll inf = 1e9 + 7;
const ll INF = 1e15;
const ld eps = 1e-9;
const db PI = atan(1) * 4;

template<typename T, typename S>inline bool upmin(T&a, const S&b) { return a > b ? a = b, 1 : 0; }
template<typename T, typename S>inline bool upmax(T&a, const S&b) { return a < b ? a = b, 1 : 0; }

ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); }
ll pow(ll a, ll b) {
	if (b == 0) {
		return 1;
	}
	if (b == 1) {
		return a;
	}
	ll ans = pow(a, b / 2);
	ans *= ans;
	ans *= b % 2 == 1 ? a : 1;
	return ans;
}

namespace SOLVE {
	vector<VI> edges;
	vector<VI> ans;
	VI lowlink;
	VI visited;
	VI firstvisit;
	VI onstack;
	VI nodeattime;
	stack<int> s;

	int time = 0;
	int children = 0;

	void dfs(int at) {
		firstvisit[at] = time;
		lowlink[at] = time;
		nodeattime[time] = at;
		onstack[at] = 1;
		s.push(at);
		time++;

		visited[at] = 1;


		for (int to : edges[at]) {
			if (!visited[to]) {
				dfs(to);	

			}
			if (onstack[to]) {
				lowlink[at] = min(lowlink[at], lowlink[to]);
			}
		}

		if (lowlink[at] == firstvisit[at]) { // start of a strongly connected component
			while (s.top() != at) {
				onstack[s.top()] = 0;
				s.pop();
			}
			onstack[s.top()] = 0;
			s.pop(); // pops off itself
		}
	}

	int low(int x) {
		if (x == nodeattime[lowlink[x]]) {
			return lowlink[x];
		}
		lowlink[x] = low(nodeattime[lowlink[x]]);
		return lowlink[x];
		
	}

	void main() {
		int n, m, a, b;
		cin >> n >> m;
		ans.resize(n);
		edges.resize(n);
		REP(i, 0, m) {
			cin >> a >> b;
			edges[a].push_back(b);
			// edges[b].push_back(a);
		}
		firstvisit.resize(n);
		lowlink.resize(n);
		visited.resize(n);
		ans.resize(n);
		onstack.resize(n);
		nodeattime.resize(n);

		REP(i, 0, n) {
			if (!visited[i]) {
				onstack[i] = 1;
				dfs(i);
				onstack[i] = 0;
			}
		}
		/*
		REP(i, 0, n) {
			cout << firstvisit[i] << ' ';
		} cout << endl;
		REP(i, 0, n) {
			cout << lowlink[i] << ' ';
		} cout << endl;
		
		*/
		int q;
		cin >> q;
		REP(i, 0, q) {
			cin >> a >> b;
			if (low(a) == low(b)) {
				cout << 1 << endl;
			}
			else {
				cout << 0 << endl;
			}
		}



	}
}


signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int t;
	//    in(t);
	t = 1;
	while (t--) {
		SOLVE::main();

	}

	return 0;
}



Measured memory_bytes: 4500