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)

#![allow(non_snake_case)]
#![allow(unused_variables)]
#![allow(dead_code)]

// https://onlinejudge.u-aizu.ac.jp/courses/library/5/GRL/all/GRL_3_C

fn main() {
    let (_N, _M): (usize, usize) = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        let mut iter = line.split_whitespace();
        (
            iter.next().unwrap().parse().unwrap(),
            iter.next().unwrap().parse().unwrap()
        )
    };
    let (_A, _B): (Vec<usize>, Vec<usize>) = {
        let (mut _A, mut _B) = (vec![], vec![]);
        for _ in 0.._M {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            _A.push(iter.next().unwrap().parse().unwrap());
            _B.push(iter.next().unwrap().parse().unwrap());
        }
        (_A, _B)
    };
    let Q: usize = {
        let mut line: String = String::new();
        std::io::stdin().read_line(&mut line).unwrap();
        line.trim().parse().unwrap()
    };
    let (u, v): (Vec<usize>, Vec<usize>) = {
        let (mut u, mut v) = (vec![], vec![]);
        for _ in 0..Q {
            let mut line: String = String::new();
            std::io::stdin().read_line(&mut line).unwrap();
            let mut iter = line.split_whitespace();
            u.push(iter.next().unwrap().parse().unwrap());
            v.push(iter.next().unwrap().parse().unwrap());
        }
        (u, v)
    };
    // snip
    let _G = {
        let mut _G = vec![std::collections::HashSet::new(); _N + 1];
        for i in 0.._M { _G[_A[i]].insert(_B[i]); }
        _G
    };
    // snip

    let (V, E) = (_N, _M);
    let (s, t) = (_A, _B);
    let G = _G;
    fn f(i: usize, G: &Vec<std::collections::HashSet<usize>>, order: &mut Vec<usize>, reachable: &mut Vec<bool>) {
        if reachable[i] {
            reachable[i] = false;
            for &j in &G[i] { f(j, G, order, reachable); }
            order.push(i);
        }
    }
    let mut order = vec![];
    let mut reachable = vec![true; V];
    for i in 0..V { f(i, &G, &mut order, &mut reachable); }
    let G_inv = {
        let mut G_inv = vec![std::collections::HashSet::new(); V];
        for i in 0..E { G_inv[t[i]].insert(s[i]); }
        G_inv
    };
    fn g(i: usize, k: usize, G_inv: &Vec<std::collections::HashSet<usize>>, scc: &mut Vec<usize>) {
        if scc[i] == 0 {
            scc[i] = k;
            for &j in &G_inv[i] { g(j, k, G_inv, scc); }
        }
    }
    let mut scc = vec![0; V];
    for (k, &i) in order.iter().rev().enumerate() { g(i, k + 1, &G_inv, &mut scc); }
    //println!("{:?}", order);
    //println!("{:?}", scc);
    let ans = (0..Q)
        .map(|i| if scc[u[i]] == scc[v[i]] { 1.to_string() } else { 0.to_string() })
        .collect::<Vec<_>>()
        .join("\n");

    println!("{}", ans);
}