Problem:
Score : 500 points

Problem Statement

There are N cards placed face down in a row. On each card, an integer 1 or 2 is written.

Let A_i be the integer written on the i-th card.

Your objective is to guess A_1, A_2, ..., A_N correctly.

You know the following facts:

For each i = 1, 2, ..., M, the value A_{X_i} + A_{Y_i} + Z_i is an even number.

You are a magician and can use the following magic any number of times:

Magic: Choose one card and know the integer A_i written on it. The cost of using this magic is 1.

What is the minimum cost required to determine all of A_1, A_2, ..., A_N?

It is guaranteed that there is no contradiction in given input.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq X_i < Y_i \leq N

1 \leq Z_i \leq 100

The pairs (X_i, Y_i) are distinct.

There is no contradiction in input. (That is, there exist integers A_1, A_2, ..., A_N that satisfy the conditions.)

Input

Input is given from Standard Input in the following format:

N M
X_1 Y_1 Z_1
X_2 Y_2 Z_2
\vdots
X_M Y_M Z_M

Output

Print the minimum total cost required to determine all of A_1, A_2, ..., A_N.

Sample Input 1

3 1
1 2 1

Sample Output 1

2

You can determine all of A_1, A_2, A_3 by using the magic for the first and third cards.

Sample Input 2

6 5
1 2 1
2 3 2
1 3 3
4 5 4
5 6 5

Sample Output 2

2

Sample Input 3

100000 1
1 100000 100

Sample Output 3

99999

Solution in Rust (1.15.1) (judge verdict: Accepted)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use libprocon::*;

fn main() {
    input! {
        N: usize,
        M: usize,
        xyz: [(usize1, usize1, usize); M],
    }
    let mut ds = DisjointSet::new(N);
    for (x, y, _) in xyz.into_iter() {
        ds.unite(x, y);
    }
    use std::collections::HashSet;
    let mut h = HashSet::new();
    for i in 0..N {
        let root = ds.root(i).unwrap();
        h.insert(root);
    }
    println!("{}", h.len());
}

// 以下、自力で解いた結果 WA (14/20)
// 目の付け所（グループ数を数えればよい）は正しいが、以下のように数えると、例えば a-b をグループ1、c-d をグループ2、としたあと、b-c が同一グループでした！という事実が明らかになった場合、崩壊する
// 連結成分の個数を数えるには Union Find を使うのが手っ取り早い。
fn wa() {
    input! {
        N: usize,
        M: usize,
        xyz: [(usize1, usize1, usize); M],
    }
    let mut groups = vec![None; N];

    let mut n_groups = 0; // グループ数
    for (x, y, _) in xyz.into_iter() {
        if groups[x].is_none() && groups[y].is_none() {
            n_groups += 1;
            groups[x] = Some(n_groups);
            groups[y] = Some(n_groups);
        }

        if let Some(g) = groups[x] {
            groups[y] = Some(g);
        }
        if let Some(g) = groups[y] {
            groups[x] = Some(g);
        }
    }

    let none_count = groups.iter().filter(|g| g.is_none()).count();
    println!("{}", none_count + n_groups);
}
*/

fn main() {
    let exe = "/tmp/bin0F3E670E";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";