Problem:
Disjoint Set

Write a program which manipulates a disjoint set S = {S1, S2, . . . , Sk}.

First of all, the program should read an integer n, then make a disjoint set where each element consists of 0, 1, ... n−1 respectively.

Next, the program should read an integer q and manipulate the set for q queries. There are two kinds of queries for different operations:

unite(x, y): unites sets that contain x and y, say Sx and Sy, into a new set.

same(x, y): determine whether x and y are in the same set.

Input

n q
com1 x1 y1
com2 x2 y2
...
comq xq yq

In the first line, n and q are given. Then, q queries are given where com represents the type of queries. '0' denotes unite and '1' denotes same operation.

Output

For each same operation, print 1 if x and y are in the same set, otherwise 0, in a line.

Constraints

1 ≤ n ≤ 10000

1 ≤ q ≤ 100000

x ≠ y

Sample Input

5 12
0 1 4
0 2 3
1 1 2
1 3 4
1 1 4
1 3 2
0 1 3
1 2 4
1 3 0
0 0 4
1 0 2
1 3 0

Sample Output

0
0
1
1
1
0
1
1

Solution in Rust (judge verdict: Accepted)

type ElementId = usize;

///
/// To read numbers from each lines
///
/// ```
/// (0..n)
///   .map(|_| read_number())
///   .collect::<Result<Vec<_>, _>>()
/// ```
///
fn read_number() -> Result<usize, String> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim()
        .parse::<usize>()
        .map_err(|err| format!("Error at read_number(): {}", err.to_string()))
}

fn read_numbers() -> Result<Vec<usize>, String> {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.split_whitespace()
        .map(|x| {
            x.parse::<usize>()
                .map_err(|err| format!("Error at read_numbers(): {}", err.to_string()))
        })
        .collect::<Result<Vec<_>, _>>()
}

#[derive(Debug)]
struct DisjointSet {
    n: usize,
    pointers: Vec<ElementId>,
    ranks: Vec<u32>,
}

impl DisjointSet {
    fn make_set(x: ElementId) -> () {
        unimplemented!();
    }

    fn find_set(&mut self, x: ElementId) -> ElementId {
        let mut current = x;
        let mut path = vec![current];
        while current != self.pointers[current] {
            current = self.pointers[current];
            path.push(current);
        }

        let root = current;
        for p in path {
            self.pointers[p] = root;
        }

        root
    }

    fn unite(&mut self, x: ElementId, y: ElementId) -> () {
        let root_x = self.find_set(x);
        let root_y = self.find_set(y);
        let rank_x = self.ranks[root_x];
        let rank_y = self.ranks[root_y];

        // Swap if the rank of the tree which contains x is smaller.
        let (x, y, root_x, root_y) = if rank_x < rank_y {
            (y, x, root_y, root_x)
        } else {
            (x, y, root_x, root_y)
        };

        self.pointers[root_y] = root_x;

        if rank_x == rank_y {
            self.ranks[x] += 1;
        };
    }
}

fn solve() -> Result<(), String> {
    let header = read_numbers()?;
    let n = header[0] as usize;
    let q = header[1];
    // println!("{:?}", (n, q));

    let mut dset = DisjointSet {
        n: n,
        pointers: (0..n).collect(),
        ranks: vec![0; n],
    };

    for i_line in 0..q {
        let line = read_numbers()?;

        if line[0] == 0 {
            dset.unite(line[1], line[2]);
        } else {
            if dset.find_set(line[1]) == dset.find_set(line[2]) {
                println!("1");
            } else {
                println!("0");
            }
        }
        //println!("{:?}", dset);
    }

    Ok(())
}

fn main() {
    match solve() {
        Err(err) => panic!("Error at solve: {}", err),
        _ => (),
    };
}