Problem:
Strongly Connected Components

A direced graph is strongly connected if every two nodes are reachable from each other. In a strongly connected component of a directed graph, every two nodes of the component are mutually reachable.

Input

A directed graph G(V, E) and a sequence of queries where each query contains a pair of nodes u and v.

|V| |E|
s0 t0
s1 t1
:
s|E|-1 t|E|-1
Q
u0 v0
u1 v1
:
uQ-1 vQ-1

|V| is the number of nodes and |E| is the number of edges in the graph. The graph nodes are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target nodes of i-th edge (directed).

ui and vi represent a pair of nodes given as the i-th query.

Output

For each query, pinrt "1" if the given nodes belong to the same strongly connected component, "0" otherwise.

Constraints

1 ≤ |V| ≤ 10,000

0 ≤ |E| ≤ 30,000

1 ≤ Q ≤ 100,000

Sample Input 1

5 6
0 1
1 0
1 2
2 4
4 3
3 2
4
0 1
0 3
2 3
3 4

Sample Output 1

1
0
1
1

Solution in C++ (judge verdict: Accepted)

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<functional>
#include<stack>
#include<queue>
#include <iomanip>
#include<map>
#include<limits>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<utility>
#include<complex>
#include<cstdlib>
#include<set>
#include<cctype>

#define DBG cerr << '!' << endl;
#define REP(i,n) for(int (i) = (0);(i) < (n);++i)
#define rep(i,s,g) for(int (i) = (s);(i) < (g);++i)
#define rrep(i,s,g) for(int (i) = (s);i >= (g);--(i))
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define SHOW1d(v,n) {for(int i = 0;i < (n);i++)cerr << v[i] << ' ';cerr << endl << endl;}
#define SHOW2d(v,i,j) {for(int aaa = 0;aaa < i;aaa++){for(int bbb = 0;bbb < j;bbb++)cerr << v[aaa][bbb] << ' ';cerr << endl;}cerr << endl;}
#define ALL(v) v.begin(),v.end()
#define Decimal fixed<<setprecision(10)

using namespace std;

typedef long long ll;
typedef vector<int> iv;
typedef vector<iv> iiv;
typedef vector<string> sv;

struct SCC{
	vector<vector<int> > G;
	vector<vector<int> > rG;
	vector<int> vs;
	vector<bool> used;
	vector<int> cmp;
	int sz,newsz;
	SCC(int n):G(n),rG(n),used(n,false),cmp(n){sz = n;}
	
	//辺を張る
	void add_edge(int from,int to){
		G[from].PB(to);
		rG[to].PB(from);
	}
	
	void dfs(int v){
		used[v] = true;
		REP(i,G[v].size()){
			if(!used[G[v][i]])dfs(G[v][i]);
		}
		vs.PB(v);
	}
	
	void rdfs(int v,int k){
		used[v] = false;
		cmp[v] = k;
		REP(i,rG[v].size()){
			if(used[rG[v][i]])rdfs(rG[v][i],k);
		}
	}
	
	//ＳＣＣ実行
	int reMake(){
		vs.clear();
		REP(i,sz)if(!used[i])dfs(i);
		int k = 0;
		for(int i = sz-1;i >= 0;i--){
			if(used[vs[i]]){
				rdfs(vs[i],k++);
			}
		}
		return newsz = k;
	}
	
	void makeList(vector<vector<int> > &v){
		REP(i,sz){
			REP(j,G[i].size()){
				if(cmp[i] == cmp[G[i][j]])continue;
				v[cmp[i]].PB(cmp[G[i][j]]);
			}
		}
	}

	void makeReverseList(vector<vector<int> > &v){
		REP(i,sz){
			REP(j,G[i].size()){
				if(cmp[i] == cmp[G[i][j]])continue;
				v[cmp[G[i][j]]].PB(cmp[i]);
			}
		}
	}
	
	int scc_node(int n){
		return cmp[n];
	}
};


int main(){
	int n,m;cin >> n >> m;
	
	SCC scc(n);
	
	REP(i,m){
		int a,b;cin >> a >> b;
		scc.add_edge(a,b);
	}
	
	scc.reMake();
	
	int q;cin >> q;
	
	REP(i,q){
		int a,b;cin >> a >> b;
		if(scc.scc_node(a) == scc.scc_node(b)){
			cout << 1 << endl;
		}
		else{
			cout << 0 << endl;
		}
	}
			
	return 0;
}