from collections import defaultdict, deque, Counter

from heapq import heappush, heappop, heapify

import math

from bisect import bisect_left, bisect_right

import random

from itertools import permutations, accumulate, combinations

import sys

import string







INF = float('inf')

def LI(): return list(map(int, sys.stdin.readline().split()))

def I(): return int(sys.stdin.readline())

def LS(): return sys.stdin.readline().split()

def S(): return sys.stdin.readline().strip()

def IR(n): return [I() for i in range(n)]

def LIR(n): return [LI() for i in range(n)]

def SR(n): return [S() for i in range(n)]

def LSR(n): return [LS() for i in range(n)]

def SRL(n): return [list(S()) for i in range(n)]

def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]

mod = 10 ** 9 + 7







class UnionFind:

    def __init__(self, n):

        # 負  : 根であることを示す。絶対値はランクを示す

        # 非負: 根でないことを示す。値は親を示す

        self.table = [-1] * n





    def root(self, x):

        if self.table[x] < 0:

            return x

        else:

            self.table[x] = self.root(self.table[x])

            return self.table[x]





    def is_same(self, x, y):

        return self.root(x) == self.root(y)





    def union(self, x, y):

        r1 = self.root(x)

        r2 = self.root(y)

        if r1 == r2:

            return

        # ランクの取得

        d1 = self.table[r1]

        d2 = self.table[r2]

        if d1 <= d2:

            self.table[r2] = r1

            if d1 == d2:

                self.table[r1] -= 1

        else:

            self.table[r1] = r2





n, m = LI()

U = UnionFind(n)

for i in range(m):

    x, y, z = LI()

    U.union(x - 1, y - 1)







print((len(set([U.root(j) for j in range(n)]))))



from collections import defaultdict, deque, Counter

from heapq import heappush, heappop, heapify

import math

from bisect import bisect_left, bisect_right

import random

from itertools import permutations, accumulate, combinations

import sys

import string







INF = float('inf')

def LI(): return list(map(int, sys.stdin.readline().split()))

def I(): return int(sys.stdin.readline())

def LS(): return sys.stdin.readline().split()

def S(): return sys.stdin.readline().strip()

def IR(n): return [I() for i in range(n)]

def LIR(n): return [LI() for i in range(n)]

def SR(n): return [S() for i in range(n)]

def LSR(n): return [LS() for i in range(n)]

def SRL(n): return [list(S()) for i in range(n)]

def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]

mod = 10 ** 9 + 7







class UnionFind:

    def __init__(self, n):

        # 負  : 根であることを示す。絶対値はランクを示す

        # 非負: 根でないことを示す。値は親を示す

        self.table = [-1] * n

        self.size = n



    def root(self, x):

        if self.table[x] < 0:

            return x

        else:

            self.table[x] = self.root(self.table[x])

            return self.table[x]





    def is_same(self, x, y):

        return self.root(x) == self.root(y)





    def union(self, x, y):

        r1 = self.root(x)

        r2 = self.root(y)

        if r1 == r2:

            return

        # ランクの取得

        d1 = self.table[r1]

        d2 = self.table[r2]

        if d1 <= d2:

            self.table[r2] = r1

            if d1 == d2:

                self.table[r1] -= 1

        else:

            self.table[r1] = r2

        self.size -= 1





n, m = LI()

U = UnionFind(n)

for i in range(m):

    x, y, z = LI()

    U.union(x - 1, y - 1)





print((U.size))











from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
from bisect import bisect_left, bisect_right
import random
from itertools import permutations, accumulate, combinations
import sys
import string

INF = float("inf")


def LI():
    return list(map(int, sys.stdin.readline().split()))


def I():
    return int(sys.stdin.readline())


def LS():
    return sys.stdin.readline().split()


def S():
    return sys.stdin.readline().strip()


def IR(n):
    return [I() for i in range(n)]


def LIR(n):
    return [LI() for i in range(n)]


def SR(n):
    return [S() for i in range(n)]


def LSR(n):
    return [LS() for i in range(n)]


def SRL(n):
    return [list(S()) for i in range(n)]


def MSRL(n):
    return [[int(j) for j in list(S())] for i in range(n)]


mod = 10**9 + 7


class UnionFind:
    def __init__(self, n):
        # 負  : 根であることを示す。絶対値はランクを示す
        # 非負: 根でないことを示す。値は親を示す
        self.table = [-1] * n

    def root(self, x):
        if self.table[x] < 0:
            return x
        else:
            self.table[x] = self.root(self.table[x])
            return self.table[x]

    def is_same(self, x, y):
        return self.root(x) == self.root(y)

    def union(self, x, y):
        r1 = self.root(x)
        r2 = self.root(y)
        if r1 == r2:
            return
        # ランクの取得
        d1 = self.table[r1]
        d2 = self.table[r2]
        if d1 <= d2:
            self.table[r2] = r1
            if d1 == d2:
                self.table[r1] -= 1
        else:
            self.table[r1] = r2


n, m = LI()
U = UnionFind(n)
for i in range(m):
    x, y, z = LI()
    U.union(x - 1, y - 1)
print((len(set([U.root(j) for j in range(n)]))))

from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
from bisect import bisect_left, bisect_right
import random
from itertools import permutations, accumulate, combinations
import sys
import string

INF = float("inf")


def LI():
    return list(map(int, sys.stdin.readline().split()))


def I():
    return int(sys.stdin.readline())


def LS():
    return sys.stdin.readline().split()


def S():
    return sys.stdin.readline().strip()


def IR(n):
    return [I() for i in range(n)]


def LIR(n):
    return [LI() for i in range(n)]


def SR(n):
    return [S() for i in range(n)]


def LSR(n):
    return [LS() for i in range(n)]


def SRL(n):
    return [list(S()) for i in range(n)]


def MSRL(n):
    return [[int(j) for j in list(S())] for i in range(n)]


mod = 10**9 + 7


class UnionFind:
    def __init__(self, n):
        # 負  : 根であることを示す。絶対値はランクを示す
        # 非負: 根でないことを示す。値は親を示す
        self.table = [-1] * n
        self.size = n

    def root(self, x):
        if self.table[x] < 0:
            return x
        else:
            self.table[x] = self.root(self.table[x])
            return self.table[x]

    def is_same(self, x, y):
        return self.root(x) == self.root(y)

    def union(self, x, y):
        r1 = self.root(x)
        r2 = self.root(y)
        if r1 == r2:
            return
        # ランクの取得
        d1 = self.table[r1]
        d2 = self.table[r2]
        if d1 <= d2:
            self.table[r2] = r1
            if d1 == d2:
                self.table[r1] -= 1
        else:
            self.table[r1] = r2
        self.size -= 1


n, m = LI()
U = UnionFind(n)
for i in range(m):
    x, y, z = LI()
    U.union(x - 1, y - 1)
print((U.size))

+        self.size = n +        self.size -= 1 -print((len(set([U.root(j) for j in range(n)])))) +print((U.size))