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)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace StronglyConnectedComponents
{
    class StronglyConnectedComponents
    {
        readonly int n;

        Dictionary<int, List<int>> G, Rev_G;
        List<int> st;
        bool[] visited;
        int[] cmp;

        public StronglyConnectedComponents(int n)
        {
            this.n = n;

            G = new Dictionary<int, List<int>>();
            Rev_G = new Dictionary<int, List<int>>();
            for (int i = 0; i < n; i++)
            {
                G.Add(i, new List<int>());
                Rev_G.Add(i, new List<int>());
            }
        }

        public void AddEdge(int from, int to)
        {
            G[from].Add(to);
            Rev_G[to].Add(from);
        }

        public void MakeSet()
        {
            st = new List<int>();
            cmp = new int[n];
            visited = new bool[n];

            for (int i = 0; i < n; i++)
            {
                if (!visited[i]) DFS(i);
            }

            visited = new bool[n];

            int cnt = 0;

            for (int i = st.Count - 1; i >= 0; i--)
            {
                int v = st[i];

                if (!visited[v]) Rev_DFS(v, cnt++);
            }
        }

        public bool IsSame(int x, int y)
        {
            return cmp[x] == cmp[y];
        }

        private void DFS(int v)
        {
            visited[v] = true;

            foreach (var next in G[v])
            {
                if (!visited[next]) DFS(next);
            }
            st.Add(v);
        }

        private void Rev_DFS(int v, int cnt)
        {
            visited[v] = true;
            cmp[v] = cnt;

            foreach (var next in Rev_G[v])
            {
                if (!visited[next]) Rev_DFS(next, cnt);
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(' ');
            int V = int.Parse(input[0]);
            int E = int.Parse(input[1]);

            StronglyConnectedComponents SCC = new StronglyConnectedComponents(V);

            for (int i = 0; i < E; i++)
            {
                input = Console.ReadLine().Split(' ');
                int s = int.Parse(input[0]);
                int t = int.Parse(input[1]);

                SCC.AddEdge(s, t);
            }

            SCC.MakeSet();

            StringBuilder sb = new StringBuilder();
            int Q = int.Parse(Console.ReadLine());

            for (int i = 0; i < Q; i++)
            {
                input = Console.ReadLine().Split(' ');
                int u = int.Parse(input[0]);
                int v = int.Parse(input[1]);

                sb.AppendLine(SCC.IsSame(u, v) ? "1" : "0");
            }
            Console.Write(sb);
        }
    }
}