import sys

sys.setrecursionlimit(2*10**5)





N, M = list(map(int, input().split()))

X, Y, Z = (

    list(zip(*(list(map(int, input().split())) for _ in range(M)))) if M else

    ((), ())

)



G = [set() for _ in range(N + 1)]

for x, y in zip(X, Y):

    G[x].add(y)

    G[y].add(x)





dp = [-1 for _ in range(N + 1)]





def f(i, k):

    for t in G[i]:

        if dp[t] == -1:

            dp[t] = k

            f(t, k)





L = 0

for i in range(1, N + 1):

    if dp[i] == -1:

        L += 1

        f(i, L)

ans = L

print(ans)

# 入力

N, M = list(map(int, input().split()))

X, Y, Z = (

    list(zip(*(list(map(int, input().split())) for _ in range(M)))) if M else

    ((), (), ())

)





# UnionFind木で連結成分の個数を数える

class UnionFindTree:

    def __init__(self, n):

        self.p = [i for i in range(n + 1)]

        self.r = [0 for _ in range(n + 1)]



    def find(self, x):

        if self.p[x] != x:

            self.p[x] = self.find(self.p[x])

        return self.p[x]



    def union(self, x, y):

        px = self.find(x)

        py = self.find(y)

        if px != py:

            if self.r[px] < self.r[py]:

                self.p[px] = py

            else:

                self.p[py] = px

                if self.r[px] == self.r[py]:

                    self.r[px] += 1



    def same(self, x, y):

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





uft = UnionFindTree(N)

for x, y in zip(X, Y):

    uft.union(x, y)

ans = len({uft.find(i) for i in range(1, N + 1)})



# 出力

print(ans)

import sys

sys.setrecursionlimit(2 * 10**5)
N, M = list(map(int, input().split()))
X, Y, Z = (
    list(zip(*(list(map(int, input().split())) for _ in range(M)))) if M else ((), ())
)
G = [set() for _ in range(N + 1)]
for x, y in zip(X, Y):
    G[x].add(y)
    G[y].add(x)
dp = [-1 for _ in range(N + 1)]


def f(i, k):
    for t in G[i]:
        if dp[t] == -1:
            dp[t] = k
            f(t, k)


L = 0
for i in range(1, N + 1):
    if dp[i] == -1:
        L += 1
        f(i, L)
ans = L
print(ans)

# 入力
N, M = list(map(int, input().split()))
X, Y, Z = (
    list(zip(*(list(map(int, input().split())) for _ in range(M))))
    if M
    else ((), (), ())
)
# UnionFind木で連結成分の個数を数える
class UnionFindTree:
    def __init__(self, n):
        self.p = [i for i in range(n + 1)]
        self.r = [0 for _ in range(n + 1)]

    def find(self, x):
        if self.p[x] != x:
            self.p[x] = self.find(self.p[x])
        return self.p[x]

    def union(self, x, y):
        px = self.find(x)
        py = self.find(y)
        if px != py:
            if self.r[px] < self.r[py]:
                self.p[px] = py
            else:
                self.p[py] = px
                if self.r[px] == self.r[py]:
                    self.r[px] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)


uft = UnionFindTree(N)
for x, y in zip(X, Y):
    uft.union(x, y)
ans = len({uft.find(i) for i in range(1, N + 1)})
# 出力
print(ans)

-import sys - -sys.setrecursionlimit(2 * 10**5) +# 入力 -    list(zip(*(list(map(int, input().split())) for _ in range(M)))) if M else ((), ()) +    list(zip(*(list(map(int, input().split())) for _ in range(M)))) +    if M +    else ((), (), ()) -G = [set() for _ in range(N + 1)] -for x, y in zip(X, Y): -    G[x].add(y) -    G[y].add(x) -dp = [-1 for _ in range(N + 1)] +# UnionFind木で連結成分の個数を数える +class UnionFindTree: +    def __init__(self, n): +        self.p = [i for i in range(n + 1)] +        self.r = [0 for _ in range(n + 1)] + +    def find(self, x): +        if self.p[x] != x: +            self.p[x] = self.find(self.p[x]) +        return self.p[x] + +    def union(self, x, y): +        px = self.find(x) +        py = self.find(y) +        if px != py: +            if self.r[px] < self.r[py]: +                self.p[px] = py +            else: +                self.p[py] = px +                if self.r[px] == self.r[py]: +                    self.r[px] += 1 + +    def same(self, x, y): +        return self.find(x) == self.find(y) -def f(i, k): -    for t in G[i]: -        if dp[t] == -1: -            dp[t] = k -            f(t, k) - - -L = 0 -for i in range(1, N + 1): -    if dp[i] == -1: -        L += 1 -        f(i, L) -ans = L +uft = UnionFindTree(N) +for x, y in zip(X, Y): +    uft.union(x, y) +ans = len({uft.find(i) for i in range(1, N + 1)}) +# 出力