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 <vector>
#include <stack>
using namespace std;

class scc {
public:
    scc(const vector<vector<int>> &edges) {
        V = edges.size();
        E.resize(V);
        rE.resize(V);
        for(int from = 0; from < V; ++from) {
            for(int to : edges[from]) {
                E[from].push_back(to);
                rE[to].push_back(from);
            }
        }
    }

    int build() {
        order.resize(V);
        used.resize(V, false);

        for(int i = 0; i < V; ++i) {
            if(!used[i]) dfs(i);
        }

        used.assign(V, false);
        int sccnum = 0;
        while(!number.empty()) {
            int cur = number.top();
            number.pop();
            if(!used[cur]) rdfs(cur, sccnum++);
        }

        return sccnum;
    }

    int operator[](int v) {
        return order[v];
    }

private:
    int V;
    vector<vector<int>> E;
    vector<vector<int>> rE;
    vector<int> order;
    vector<bool> used;
    stack<int> number;

    void dfs(int v) {
        used[v] = true;
        for(int to : E[v]) {
            if(!used[to]) dfs(to);
        }
        number.push(v);
    }

    void rdfs(int v, int k) {
        used[v] = true;
        order[v] = k;
        for(int to : rE[v]) {
            if(!used[to]) rdfs(to, k);
        }
    }
};


#include <iostream>
int main() {
    int V, E;
    cin >> V >> E;
    vector<vector<int>> edges(V);
    while(E--) {
        int s, t;
        cin >> s >> t;
        edges[s].push_back(t);
    }

    scc comp(edges);
    comp.build();
    
    int Q;
    cin >> Q;
    while(Q--) {
        int u, v;
        cin >> u >> v;
        cout << (comp[u] == comp[v] ? 1 : 0) << endl;
    }
}