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 JAVA (judge verdict: Runtime Error)

import java.util.*;

public class Main {
	static int V;
	static int E;
	static ArrayList<Integer>[] g;

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		V = sc.nextInt();
		E = sc.nextInt();
		g = new ArrayList[V];
		for (int i = 0; i < V; ++i)
			g[i] = new ArrayList<>();
		for (int i = 0; i < E; ++i) {
			int s = sc.nextInt();
			int t = sc.nextInt();
			g[s].add(t);
		}
		vis = new boolean[V];
		marked = new boolean[V];
		cmp = new int[V];
		low = new int[V];
		id = new int[V];
		for (int i = 0; i < V; ++i) {
			if (!marked[i]) {
				dfs(i);
			}
		}
		int Q = sc.nextInt();
		for (int i = 0; i < Q; ++i) {
			int u = sc.nextInt();
			int v = sc.nextInt();
			if (cmp[u] == cmp[v]) {
				System.out.println("1");
			} else {
				System.out.println("0");
			}
		}
	}

	static ArrayDeque<Integer> stack = new ArrayDeque<>();
	static boolean[] vis;
	static int[] low;
	static int[] id;
	static int curId = 0;
	static boolean[] marked;
	static int[] cmp;
	static int col = 0;

	static void dfs(int cur) {
		vis[cur] = true;
		stack.addFirst(cur);
		id[cur] = curId++;
		low[cur] = id[cur];
		for (int dst : g[cur]) {
			if (marked[dst])
				continue;
			if (!vis[dst]) {
				dfs(dst);
				low[cur] = Math.min(low[cur], low[dst]);
			} else {
				low[cur] = Math.min(low[cur], id[dst]);
			}
		}
		if (id[cur] == low[cur]) {
			int v;
			do {
				v = stack.removeFirst();
				cmp[v] = col;
				marked[v] = true;
			} while (v != cur);
			++col;
		}
		return;
	}
}