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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {
        int n,m;
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer in=new StringTokenizer(br.readLine());
        n=Integer.parseInt(in.nextToken());
        m=Integer.parseInt(in.nextToken());
        in=null;
        Union_Find tree=new Union_Find(n);
        for(int i=0;i<m;i++){
            in=new StringTokenizer(br.readLine());
            int a=Integer.parseInt(in.nextToken()),b=Integer.parseInt(in.nextToken());
            in=null;
            tree.Union(a,b);
        }
        br=null;
        System.out.println(tree.get_tree(n));
    }
}
class Union_Find{
    private int[] t,s;
    public Union_Find(int max_length){
        t=new int[max_length];
        s=new int[max_length];
        for(int i=0;i<max_length;i++){
            t[i]=i;
            s[i]=1;
        }
    }
    void Union(int x,int y){
        if (same(x, y)) return;
        x--;y--;
        int tx = Find(x), ty = Find(y);
        if (s[tx] < s[ty]) {
            s[ty] += s[tx];
            t[tx] = ty;
        }
        else if (s[tx] > s[ty]) {
            s[tx] += s[ty];
            t[ty] = tx;
        }
        else if (tx > ty) {
            t[tx] = ty;
            s[ty] += s[tx];
        }
        else {
            t[ty] = tx;
            s[tx] += s[ty];
        }
    }
    int Find(int n) {
        if (t[n] == n)
            return n;
        else
            return t[n] = Find(t[n]);
    }
    boolean same(int x, int y) {
        return Find(x-1) == Find(y-1);
    }
    int get_Size(int a) {
        return s[a-1];
    }
    int get_tree(int size){
        HashSet<Integer> st=new HashSet<>();
        for(int i=0;i<size;i++){
            st.add(Find(i));
        }
        return st.size();
    }
}