class UnionFind:

    def __init__(self, n):

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

        self.rank = [0] * (n+1)



    # 検索

    def find(self, x):

        if self.par[x] == x:

            return x

        else:

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

            return self.par[x]



    # 併合

    def union(self, x, y):

        x = self.find(x)

        y = self.find(y)

        if self.rank[x] < self.rank[y]:

            self.par[x] = y

        else:

            self.par[y] = x

            if self.rank[x] == self.rank[y]:

                self.rank[x] += 1



    # 同じ集合に属するか判定

    def same_check(self, x, y):

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

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

a=UnionFind(N)

for i in range(M):

    X,Y,Z=list(map(int,input().split()))

    if a.same_check(X,Y):

        pass

    else:

        a.union(X,Y)

answer=set()

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

    answer.add(a.find(i))

print((len(answer)))

class UnionFind:

    def __init__(self, n):

        self.par = [-1]*(n+1)

        self.sizes=[1]*(n+1)



    # 検索

    def find(self, x):

        if self.par[x]<0:

            return x

        else:

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

            return self.par[x]



    # 併合

    def union(self, x, y):

        x = self.find(x)

        y = self.find(y)

        if x==y:

            return

        d1=self.par[x]

        d2=self.par[y]

        if d1<=d2:

            self.par[y]=x

            self.sizes[x]=self.sizes[x]+self.sizes[y]

            if d1==d2:

                self.par[x]=self.par[x]-1

        else:

            self.par[x]=y

            self.sizes[y]=self.sizes[x]+self.sizes[y]



    # 同じ集合に属するか判定

    def same_check(self, x, y):

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



    #サイズ

    def size(self,x):

        return self.sizes[find(x)]



    #木の数

    def number(self):

        count=0

        for i in self.par[1:]:

            if i<0:

                count=count+1

        return count

        

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

U=UnionFind(N)

for i in range(M):

    X,Y,Z=list(map(int,input().split()))

    U.union(X,Y)

print((U.number()))

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [0] * (n + 1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)


N, M = list(map(int, input().split()))
a = UnionFind(N)
for i in range(M):
    X, Y, Z = list(map(int, input().split()))
    if a.same_check(X, Y):
        pass
    else:
        a.union(X, Y)
answer = set()
for i in range(1, N + 1):
    answer.add(a.find(i))
print((len(answer)))

class UnionFind:
    def __init__(self, n):
        self.par = [-1] * (n + 1)
        self.sizes = [1] * (n + 1)

    # 検索
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    # 併合
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        d1 = self.par[x]
        d2 = self.par[y]
        if d1 <= d2:
            self.par[y] = x
            self.sizes[x] = self.sizes[x] + self.sizes[y]
            if d1 == d2:
                self.par[x] = self.par[x] - 1
        else:
            self.par[x] = y
            self.sizes[y] = self.sizes[x] + self.sizes[y]

    # 同じ集合に属するか判定
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

    # サイズ
    def size(self, x):
        return self.sizes[find(x)]

    # 木の数
    def number(self):
        count = 0
        for i in self.par[1:]:
            if i < 0:
                count = count + 1
        return count


N, M = list(map(int, input().split()))
U = UnionFind(N)
for i in range(M):
    X, Y, Z = list(map(int, input().split()))
    U.union(X, Y)
print((U.number()))

-        self.par = [i for i in range(n + 1)] -        self.rank = [0] * (n + 1) +        self.par = [-1] * (n + 1) +        self.sizes = [1] * (n + 1) -        if self.par[x] == x: +        if self.par[x] < 0: -        if self.rank[x] < self.rank[y]: +        if x == y: +            return +        d1 = self.par[x] +        d2 = self.par[y] +        if d1 <= d2: +            self.par[y] = x +            self.sizes[x] = self.sizes[x] + self.sizes[y] +            if d1 == d2: +                self.par[x] = self.par[x] - 1 +        else: -        else: -            self.par[y] = x -            if self.rank[x] == self.rank[y]: -                self.rank[x] += 1 +            self.sizes[y] = self.sizes[x] + self.sizes[y] +    # サイズ +    def size(self, x): +        return self.sizes[find(x)] + +    # 木の数 +    def number(self): +        count = 0 +        for i in self.par[1:]: +            if i < 0: +                count = count + 1 +        return count + -a = UnionFind(N) +U = UnionFind(N) -    if a.same_check(X, Y): -        pass -    else: -        a.union(X, Y) -answer = set() -for i in range(1, N + 1): -    answer.add(a.find(i)) -print((len(answer))) +    U.union(X, Y) +print((U.number()))