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

fn solve(graph: Vec<Vec<usize>>) -> Vec<usize> {
    let size = graph.len();
    let mut assign = vec![size + 1; size];
    let mut preorder = vec![size + 1; size];
    let mut order = 0;
    let mut component = 0;
    for i in 0..size {
        if preorder[i] <= size {
            continue;
        }
        let mut stack = vec![];
        let mut not_assigned = vec![];
        let mut intermidiate = vec![];
        stack.push(i);
        'outer: while !stack.is_empty() {
            let from = *stack.last().unwrap();
            if preorder[from] == size + 1 {
                // Preorder procedure.
                preorder[from] = order;
                order += 1;
                not_assigned.push(from);
                intermidiate.push(from);
            }
            for &to in &graph[from] {
                if preorder[to] == size + 1 {
                    stack.push(to);
                    continue 'outer;
                } else if assign[to] == size + 1 {
                    while let Some(top) = intermidiate.pop() {
                        if preorder[top] <= preorder[to] {
                            intermidiate.push(top);
                            break;
                        }
                    }
                }
            }
            // Postorder.
            let from = stack.pop().unwrap(); // safe.
            let top = intermidiate.pop().unwrap();
            if top == from {
                while let Some(top_of_not_assigned) = not_assigned.pop() {
                    assign[top_of_not_assigned] = component;
                    if top_of_not_assigned == top {
                        break;
                    }
                }
                component += 1;
            } else {
                intermidiate.push(top);
            }
        }
    }
    assign
}

use std::io::{BufRead, BufReader};
fn main() {
    let mut read = BufReader::new(std::io::stdin())
        .lines()
        .filter_map(|e| e.ok());
    let (v, e) = {
        let line = read.next().unwrap();
        let line: Vec<&str> = line.split(' ').collect();
        let v: usize = line[0].parse().unwrap();
        let e: usize = line[1].parse().unwrap();
        (v, e)
    };
    let graph = {
        let mut graph: Vec<Vec<_>> = vec![vec![]; v]; // Adj list
        for _ in 0..e {
            let edge = read.next().unwrap();
            let mut edge = edge.split(' ');
            let start: usize = edge.next().unwrap().parse().unwrap();
            let end: usize = edge.next().unwrap().parse().unwrap();
            graph[start].push(end);
        }
        graph
    };
    let component = solve(graph);
    read.next();
    for line in read {
        let line: Vec<_> = line.split(' ').collect();
        let start: usize = line[0].parse().unwrap();
        let end: usize = line[1].parse().unwrap();
        if component[start] == component[end] {
            println!("1");
        } else {
            println!("0");
        }
    }
}