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 C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdint>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <valarray>
#include <vector>

#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

template <class T>
T peak_and_pop(std::queue<T>& q)
{
    assert(!q.empty());
    T t = move(q.front());
    q.pop();
    return t;
}

struct edge_t {
    edge_t(int n, int d):next(n),distance(d){}
    int next = 0;
    int distance = 0;
};

constexpr int unknown = 0;

struct node_t {
    int num = unknown;
    vector<int> same_node;
    vector<int> different_node;
};

void solution()
{
    int n,m;
    cin >> n >> m;
    vector<node_t> nodes(n);

    const auto connect = [&](int u, int v, int w){
        if(w % 2 == 0){
            nodes[u].same_node.push_back(v);
            nodes[v].same_node.push_back(u);
        }else{
            nodes[u].different_node.push_back(v);
            nodes[v].different_node.push_back(u);
        }
    };

    rep(i,m){
        int x,y,z;
        cin >> x >> y >> z;
        connect(x-1, y-1, z);
    }

    int cost = 0;
    queue<int> visit_queue;
    rep(i,n){
        if(nodes[i].num == unknown){
            nodes[i].num = 1;
            visit_queue.push(i);
            cost += 1;
        }
        while(!visit_queue.empty()){
            auto& node = nodes.at(peak_and_pop(visit_queue));
            assert(node.num != unknown);
            for(auto& j : node.same_node){
                if(nodes[j].num == unknown){
                    nodes[j].num = node.num;
                    visit_queue.push(j);
                }
            }
            for(auto& j : node.different_node){
                if(nodes[j].num == unknown){
                    nodes[j].num = node.num == 2 ? 1 : 2;
                    visit_queue.push(j);
                }
            }
        }
    }
    cout << cost << '\n';
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(10);
    solution();
    return 0;
}