Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Connected Components

Write a program which reads relations in a SNS (Social Network Service), and judges that given pairs of users are reachable each other through the network.

Input

In the first line, two integer $n$ and $m$ are given. $n$ is the number of users in the SNS and $m$ is the number of relations in the SNS. The users in the SNS are identified by IDs $0, 1, ..., n-1$.

In the following $m$ lines, the relations are given. Each relation is given by two integers $s$ and $t$ that represents $s$ and $t$ are friends (and reachable each other).

In the next line, the number of queries $q$ is given. In the following $q$ lines, $q$ queries are given respectively. Each query consists of two integers $s$ and $t$ separated by a space character.

Output

For each query, print "yes" if $t$ is reachable from $s$ through the social network, "no" otherwise.

Constraints

$2 \leq n \leq 100,000$

$0 \leq m \leq 100,000$

$1 \leq q \leq 10,000$

Sample Input

10 9
0 1
0 2
3 4
5 7
5 6
6 7
6 8
7 8
8 9
3
0 1
5 9
1 3

Sample Output

yes
yes
no

Solution in Rust (judge verdict: Accepted)

#![allow(dead_code)]
/// Union-Find版・DFS版を両方記載
use std::io::{self, Read};
use std::str::FromStr;
pub struct Scanner<R: Read> {
    reader: R,
}
impl<R: Read> Scanner<R> {
    pub fn new(reader: R) -> Scanner<R> {
        Scanner { reader: reader }
    }
    pub fn read<T: FromStr>(&mut self) -> T {
        let s = self
            .reader
            .by_ref()
            .bytes()
            .map(|c| c.expect("failed to read char") as char)
            .skip_while(|c| c.is_whitespace())
            .take_while(|c| !c.is_whitespace())
            .collect::<String>();
        s.parse::<T>().ok().expect("failed to parse token")
    }
}

struct UnionFind {
    /// nodes[i] = iなら、そのノードは根
    nodes: Vec<usize>,
}

impl UnionFind {
    fn new(size: usize) -> UnionFind {
        UnionFind {
            nodes: (0..size).map(|i| i).collect(),
        }
    }

    fn root(&mut self, idx: usize) -> usize {
        if self.nodes[idx] == idx {
            idx
        } else {
            // 自身の親を根にして経路圧縮
            let p = self.nodes[idx];
            let r = self.root(p);
            self.nodes[idx] = r;
            self.nodes[idx]
        }
    }

    fn same(&mut self, x: usize, y: usize) -> bool {
        self.root(x) == self.root(y)
    }

    fn unite(&mut self, x: usize, y: usize) {
        // ランクなし併合
        let x = self.root(x);
        let y = self.root(y);
        if x != y {
            self.nodes[x] = y;
        }
    }
}

/// Union Findで解く場合
fn solve_unionfind() {
    let sin = io::stdin();
    let sin = sin.lock();
    let mut sc = Scanner::new(sin);

    let n: usize = sc.read();
    let m: usize = sc.read();

    let mut nodes = UnionFind::new(n);
    for _ in 0..m {
        let s: usize = sc.read();
        let t: usize = sc.read();
        nodes.unite(s, t);
    }

    let q: usize = sc.read();
    for _ in 0..q {
        let s: usize = sc.read();
        let t: usize = sc.read();
        if nodes.same(s, t) {
            println!("yes");
        } else {
            println!("no");
        }
    }
}

use std::collections::VecDeque;
fn solve_graph(){
    let sin = io::stdin();
    let sin = sin.lock();
    let mut sc = Scanner::new(sin);

    let n: usize = sc.read();
    let m: usize = sc.read();

    let mut nodes: Vec<Vec<usize>> = vec![vec![]; n];
    for _ in 0..m {
        let s: usize = sc.read();
        let t: usize = sc.read();

        nodes[s].push(t);
        nodes[t].push(s);
    }
    let mut color: Vec<u64> = vec![0; n];   // 0が未訪問
    let mut c = 0;

    // dfs
    for i in 0..n {
        if color[i] != 0 {
            continue;
        } 
        c += 1;
        color[i] = c;

        let mut que = VecDeque::new();
        que.push_back(i);
        while let Some(idx) = que.pop_back() {
            for i in nodes[idx].iter() {
                if color[*i] == 0 {
                    color[*i] = color[idx];
                    que.push_back(*i);
                }
            }
        }
    }


    let q: usize = sc.read();
    for _ in 0..q {
        let s: usize = sc.read();
        let t: usize = sc.read();
        if color[s] == color[t] {
            println!("yes");
        } else {
            println!("no");
        }
    }
}

fn main() {
    solve_graph();
    // solve_unionfind();
}