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

#include<bits/stdc++.h>
using namespace std;

/*
  // Time complexity
  O(v + e) (v: 頂点の数, e: 辺の数)

  // Initialization
  StronglyConnectedComponents scc = StronglyConnectedComponents(n); (n: 頂点の数)
  scc.add_edge(u, v, c); (u: start, v: to)
  scc.build();
*/

struct StronglyConnectedComponents {
    int n;
    vector< vector< int > > g;
    vector< vector< int > > rg;
    vector< bool > used;
    vector< int > order, comp;
    StronglyConnectedComponents(int n) : n(n), g(n), rg(n), used(n, false), comp(n, -1) { }
    void add_edge(int u, int v) {
        g[u].push_back(v);
        rg[v].push_back(u);
    }
    void build() {
        for (int i = 0; i < n; ++i) {
            if(!used[i]) dfs(i);
        }
        int cnt = 0;
        reverse(order.begin(), order.end());
        for(int i : order) {
            if(comp[i] == -1) rdfs(i, cnt++);
        }
    }
    int operator[](int k) {
        return comp[k];
    }
    void dfs(int idx) {
        used[idx] = true;
        for (int to : g[idx]) {
            if (!used[to]) dfs(to);
        }
        order.push_back(idx);
    }
    void rdfs(int idx, int cnt) {
        comp[idx] = cnt;
        for (int to : rg[idx]) {
            if(comp[to] == -1) rdfs(to, cnt);
        }
    }
};

/*
    verified http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_3_C&lang=jp
*/
int main() {
    int v, e; cin >> v >> e;
    StronglyConnectedComponents scc = StronglyConnectedComponents(v);
    for (int i = 0; i < e; ++i) {
        int s, t; cin >> s >> t;
        scc.add_edge(s, t);
    }
    scc.build();
    int q; cin >> q;
    vector< int > us(q), vs(q);
    for (int i = 0; i < q; ++i) {
        cin >> us[i] >> vs[i];
    }
    for (int i = 0; i < q; ++i) {
        cout << (scc[us[i]] == scc[vs[i]] ? 1 : 0) << endl;
    }
}