/*
csc -debug E.cs && mono --debug E.exe <<< "3 1
1 2 1"
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Reflection;

public class HelloWorld {
    public static void SolveCodeForces() {
        var N = cin.NextInt();
        var M = cin.NextInt();

        var union = new UnionFind(N);
        for (var i = 0; i < M; i++) {
            var xyz = cin.IntArray();
            var x = xyz[0];
            var y = xyz[1];
            var z = xyz[2];
            union.Union(x-1, y-1);
        }

        for (var i = 0; i < N; i++)
            union.Find(i);

        System.Console.WriteLine(union.leaders.Distinct().Count());
    }

    static Scanner cin = new Scanner();
    static StringBuilder cout = new StringBuilder();

    static public void Main () {
        SolveCodeForces();
        // IncreaseStack(SolveCodeForces);
        // System.Console.Write(cout.ToString());
    }

    public static void IncreaseStack(ThreadStart action, int stackSize = 128000000)
    {
        var thread = new Thread(action, stackSize);
        thread.Start();
        thread.Join();
    }
}

public class UnionFind
{
    public readonly int[] leaders;
    private readonly int[] ranks;

    public UnionFind(int count)
    {
        ClustersCount = count;
        leaders = new int[count];
        for (var i = 0; i < count; i++)
            leaders[i] = i;
        ranks = new int[count];
    }

    public int ClustersCount { get; private set; }

    public void Union(int x, int y)
    {
        var from = Find(x);
        var to = Find(y);

        if (from == to)
            return;

        ClustersCount--;

        var rfrom = ranks[from];
        var rto = ranks[to];

        if (rfrom == rto)
        {
            leaders[from] = to;
            ranks[to]++;
        }
        else if (rfrom < rto)
        {
            leaders[from] = to;
        }
        else
        {
            leaders[to] = from;
        }
    }

    public int Find(int i)
    {
        var prev = i;

        var leader = leaders[prev];
        while (leader != prev)
        {
            prev = leader;
            leader = leaders[leader];
        }

        leaders[i] = leader;

        return leader;
    }
}

public static class Helpers {
    public static T[] CreateArray<T>(int length, Func<int, T> itemCreate) {
        var result = new T[length];
        for (var i = 0; i < result.Length; i++)
            result[i] = itemCreate(i);
        return result;
    }
}

public class Scanner
{
    private string[] line = new string[0];
    private int index = 0;

    public string Next() {
        if (line.Length <= index) {
            line = Console.ReadLine().Split(' ');
            index = 0;
        }
        var res = line[index];
        index++;
        return res;
    }

    public int NextInt() {
        return int.Parse(Next());
    }

    public long NextLong() {
        return long.Parse(Next());
    }

    public ulong NextUlong() {
        return ulong.Parse(Next());
    }

    public string[] Array() {
        line = Console.ReadLine().Split(' ');
        index = line.Length;
        return line;
    }

    public int[] IntArray(int emptyPrefixLen = 0) {
        var array = Array();
        var result = new int[emptyPrefixLen + array.Length];
        for (int i = 0; i < array.Length; i++)
            result[emptyPrefixLen + i] = int.Parse(array[i]);
        return result;
    }

    public long[] LongArray() {
        var array = Array();
        var result = new long[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = long.Parse(array[i]);
        return result;
    }

    public ulong[] UlongArray() {
        var array = Array();
        var result = new ulong[array.Length];
        for (int i = 0; i < array.Length; i++)
            result[i] = ulong.Parse(array[i]);
        return result;
    }
}

Measured memory_bytes: 19772