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# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;

namespace AtCoder.Question
{
    public class QuestionE
    {
        public static void Main(string[] args)
        {
            var (n, m) = ReadHelper.ReadValue<int, int>();
            var xyzm = new List<(int x, int y, int z)>();
            for (int i = 0; i < m; i++)
            {
                var xyz = ReadHelper.ReadValue<int, int, int>();
                xyzm.Add(xyz);
            }

            var unionFind = new UnionFind(n);
            foreach (var xyz in xyzm)
            {
                unionFind.Unite(xyz.x, xyz.y);
            }
            Console.WriteLine(unionFind.Count());
        }

        class UnionFind
        {
            int[] par;
            internal UnionFind(int n)
            {
                par = new int[n + 1];
                for (int i = 0; i < n + 1; i++)
                {
                    par[i] = i;
                }
            }

            internal int Root(int x)
            {
                if (par[x] == x) return x;
                return Root(par[x]);
            }

            internal void Unite(int x, int y)
            {
                var rx = Root(x);
                var ry = Root(y);
                if (rx == ry) return;
                par[rx] = ry;
            }

            internal bool Same(int x, int y)
            {
                return Root(x) == Root(y);
            }

            internal int Count()
            {
                var hs = new HashSet<int>();
                for (int i = 1; i < par.Length; i++)
                {
                    hs.Add(Root(i));
                }
                return hs.Count;
            }
        }

        static class ReadHelper
        {
            internal static T ReadValue<T>()
            {
                return (T)Convert.ChangeType(Console.ReadLine(), typeof(T));
            }
            internal static (T1, T2) ReadValue<T1, T2>()
            {
                var input = Console.ReadLine().Split(' ');
                return ((T1)Convert.ChangeType(input[0], typeof(T1)), (T2)Convert.ChangeType(input[1], typeof(T2)));
            }
            internal static (T1, T2, T3) ReadValue<T1, T2, T3>()
            {
                var input = Console.ReadLine().Split(' ');
                return ((T1)Convert.ChangeType(input[0], typeof(T1)), (T2)Convert.ChangeType(input[1], typeof(T2)), (T3)Convert.ChangeType(input[2], typeof(T3)));
            }
            internal static (T1, T2, T3, T4) ReadValue<T1, T2, T3, T4>()
            {
                var input = Console.ReadLine().Split(' ');
                return ((T1)Convert.ChangeType(input[0], typeof(T1)), (T2)Convert.ChangeType(input[1], typeof(T2)), (T3)Convert.ChangeType(input[2], typeof(T3)), (T4)Convert.ChangeType(input[3], typeof(T4)));
            }
            internal static T[] ReadValues<T>()
            {
                var input = Console.ReadLine().Split(' ');
                return input.Select(x => (T)Convert.ChangeType(x, typeof(T))).ToArray();
            }
        }

        static class MathAlgorithm
        {
            internal static bool IsPrime(long n)
            {
                if (n == 2) return true;
                if (n < 2 || n % 2 == 0) return false;
                var sqrt = Math.Sqrt(n);
                for (int i = 3; i <= sqrt; i += 2) if (n % i == 0) return false;
                return true;
            }
            internal static IEnumerable<long> EnumeratePrimes(long n)
            {
                var i = 2L;
                while (i * i <= n)
                {
                    if (n % i == 0)
                    {
                        n /= i;
                        yield return i;
                    }
                    else
                    {
                        i += i == 2 ? 1 : 2;
                    }
                }
                if (n != 1) yield return n;
            }
        }
    }
}