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 Java (OpenJDK 11.0.6) (judge verdict: Wrong Answer)


import java.util.Scanner;

public class Main {

    static Scanner scanner;

    public static void main(String[] args) {
        scanner = new Scanner(System.in);

        int N=gi();
        int M=gi();
        UnionFind uf=new UnionFind(N);

        for (int i=0;i<M;i++) {
        	int x=gi()-1;
        	int y=gi()-1;
        	int z=gi();
        	uf.union(x, y);
        }

        System.out.println(uf.getKindNum());
    }

    public static class UnionFind {

    	int[] parent;
    	public UnionFind(int n) {
    		parent=new int[n];
    		for(int i=0; i<parent.length;i++) {
    			parent[i]=-1;
    		}
    	}

    	public int find(int n) {
    		if(parent[n]<0) {
    			return n;
    		} else {
    			parent[n]=find(parent[n]);
    			return parent[n];
    		}

    	}

    	public void union(int n1, int n2) {
    		int r1=find(n1);
    		int r2=find(n2);
    		if(r1==r2) return;

    		if(getRunk(r1)<getRunk(r2)) {
    			parent[n1]=r2;
    		} else {
    			parent[n2]=r1;
    			if(getRunk(r1)==getRunk(r2)) parent[r1]--;
    		}
    	}

    	public int getRunk(int n) {
            return -parent[find(n)];
    	}

    	public int getKindNum() {
            int ret=0;
            for (int i=0; i<parent.length;i++) {
            	if(parent[i]<0) {
            		ret++;
            	}
            }
            return ret;
    	}

    	public boolean same(int n1, int n2) {
    		return find(n1)==find(n2);
    	}
    }

    // 文字列として入力を取得
    public static String gs() {
         return scanner.next();
    }

    // intとして入力を取得
    public static int gi() {
         return Integer.parseInt(scanner.next());
    }

    // longとして入力を取得
    public static long gl() {
         return Long.parseLong(scanner.next());
    }

    // doubleとして入力を取得
    public static double gd() {
         return Double.parseDouble(scanner.next());
    }
}