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++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0; i<(n); i++)
#define FOR(i,x,n) for(int i=x; i<(n); i++)
#define ALL(n) begin(n),end(n)
#define MOD (1000000007)
#define INF (1e9)
#define INFL (1e18)

typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
template<class T>using arr=vector<vector<T>>;
template<class T>void pr(T x){cout << x << endl;}
template<class T>void prvec(vector<T>& a){rep(i, a.size()-1){cout << a[i] << " ";} cout << a[a.size()-1] << endl;}
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
arr<int> G, rG;
int v, e;
vector<bool> seen;
vector<int> backed;
vector<int> setnum;

void dfs1(int n){
    seen[n] = true;
    for(auto i: G[n]){
        if(seen[i]) continue;
        dfs1(i);
    }
    backed.push_back(n);
}

void dfs2(int n, int g){
    seen[n] = true;
    setnum[n] = g;
    for(auto i: rG[n]){
        if(seen[i]) continue;
        dfs2(i, g);
    }
}

int main()
{
    cin >> v >> e;
    G.resize(v);
    rG.resize(v);
    seen.resize(v, false);
    setnum.resize(v);
    rep(i, e){
        int f, t; cin >> f >> t;
        G[f].push_back(t);
        rG[t].push_back(f);
    }
    rep(i, v){
        if(seen[i]) continue;
        dfs1(i);
    }

    // prvec(backed);

    seen.assign(v, false);
    int group=0;
    for(int i=v-1; i>=0; i--){
        if(seen[backed[i]]) continue;
        dfs2(backed[i], group++);
    }

    // prvec(setnum);

    int q; cin >> q;
    int s, t;
    rep(i, q){
        cin >> s >> t;
        if(setnum[s]==setnum[t]) pr(1);
        else pr(0);
    }
    return 0;}