// Slower C++ solution:
#include  <bits/stdc++.h>

#define rep(i,n) for(int (i)=0;(i)<(n);(i)++)

using namespace std;



const int vmax=100010;



vector<int> graph[vmax],ord,low,scc,par;

stack<int>s;



void dfs(int v,int p,int &k){

	ord[v]=k++;

	low[v]=ord[v];

	par[v]=p;

	s.push(v); // S

	for(auto &i:graph[v]){

		if(ord[i]==-1){

			dfs(i,v,k);

			low[v]=min(low[v],low[i]);

		//}else if(i!=p){    // B,A

		}else if(scc[i]==-1){ // S

			low[v]=min(low[v],ord[i]);

		}

	}

	if(ord[v]==low[v]){

		while(1){

			int u=s.top();s.pop();

			scc[u]=v;

			if(u==v) break;

		}

	}  //S

}



void lowlink(int n){

	int k=0;

	ord.assign(n,-1),low.resize(n);

	scc.assign(n,-1),par.resize(n);

	rep(i,n) if(ord[i]==-1) dfs(i,-1,k);

}



int main(void){

	int v,e;

	cin >> v >> e;

	rep(loop,e){

		int a,b;

		cin >> a >> b;

		graph[a].push_back(b);

		// graph[b].push_back(a); // B,A



	}

	lowlink(v);



/*	rep(i,v){

		cout << "ord[" << i << "]=" << ord[i]  << endl;

		cout << "low[" << i << "]=" << low[i]  << endl;

	}

*/



// Bridge

/*	vector<pair<int,int>> bridge;

	rep(i,v){

		int j=par[i];

		if(j==-1)

			continue;

		if(ord[i] < low[j] || ord[j] < low[i] ){

			auto in=make_pair(i,j);

			if(in.second<=in.first) swap(in.first,in.second);

			bridge.pb(in);

		}

	}

	sort(bridge.begin(),bridge.end());

	for(auto &i:bridge)

		cout << i.first << " " << i.second << endl;

*/



// Articulation Points

/*	vi articulation_point;

	rep(i,v){

		if(i){

			bool ok=false;

			for(auto &j:graph[i]){

				if(i==par[j]&&ord[i]<=low[j])

					ok=true;

			}

			if(ok) articulation_point.push_back(i);

		}else{

			int d=0;

			rep(j,v) if(par[j]==0) d++;

			if(d>=2) articulation_point.push_back(i);

		}

	}

	sort(articulation_point.begin(),articulation_point.end());

	for(auto &i:articulation_point)

		cout << i << endl;

*/

// Strongly Connected Components



	int q;

	cin >> q;

	rep(loop,q){

		int a,b;

		cin >> a >> b;

		cout << (scc[a]==scc[b]) << endl;

	}



	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.4824890650643328x):
#include <bits/stdc++.h>



#define _overload(_1,_2,_3,name,...) name

#define _rep(i,n) _range(i,0,n)

#define _range(i,a,b) for(int i=int(a);i<int(b);++i)

#define rep(...) _overload(__VA_ARGS__,_range,_rep,)(__VA_ARGS__)



#define _rrep(i,n) _rrange(i,n,0)

#define _rrange(i,a,b) for(int i=int(a)-1;i>=int(b);--i)

#define rrep(...) _overload(__VA_ARGS__,_rrange,_rrep,)(__VA_ARGS__)



#define _all(arg) begin(arg),end(arg)

#define uniq(arg) sort(_all(arg)),(arg).erase(unique(_all(arg)),end(arg))

#define getidx(ary,key) lower_bound(_all(ary),key)-begin(ary)

#define clr(a,b) memset((a),(b),sizeof(a))

#define bit(n) (1LL<<(n))

#define popcount(n) (__builtin_popcountll(n))



template<class T>bool chmax(T &a, const T &b) { return (a<b)?(a=b,1):0;}

template<class T>bool chmin(T &a, const T &b) { return (b<a)?(a=b,1):0;}



using namespace std;



using node=struct{int to;};

using G=vector<vector<node>>;



tuple<vector<int>,G> scc(const G &graph){

	int n=graph.size(),k=0;

	vector<int> ord(n,-1),low(n),comp(n,-1),par(n);

	stack<int>s;



	function<void(int,int,int&)> dfs=[&](int v,int p,int &k){

		ord[v]=k++,low[v]=ord[v],par[v]=p;

		s.push(v);



		for(auto &e:graph[v]){

			if(ord[e.to]==-1){

				dfs(e.to,v,k);

				low[v]=min(low[v],low[e.to]);

			}else if(comp[e.to]==-1){

				low[v]=min(low[v],ord[e.to]);

			}

		}



		if(ord[v]==low[v]){

			while(1){

				int u=s.top();s.pop();

				comp[u]=v;

				if(u==v) break;

			}

		}

	};



	rep(v,n) if(ord[v]==-1) dfs(v,-1,k);

	G dag(k);

	rep(v,n) for(auto &e:graph[v]) if(comp[v]!=comp[e.to]) dag[comp[v]].push_back(e);

	return make_tuple(comp,dag);

}



int main(void){

	int v,e;

	cin >> v >> e;



	G graph(v);

	rep(loop,e){

		int a,b;

		cin >> a >> b;

		graph[a].push_back({b});

	}



	vector<int> comp;

	tie(comp,ignore)=scc(graph);



	int q;

	cin >> q;

	rep(loop,q){

		int a,b;

		cin >> a >> b;

		cout << (comp[a]==comp[b]) << endl;

	}

	return 0;

}