import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

input=lambda :sys.stdin.readline().rstrip()

class UnionFind(object):

    def __init__(self,n):

        self.__par=list(range(n))

        self.__rank=[0]*n

        self.__size=[1]*n

        self.__connected=n



    def root(self,k):

        if(self.__par[k]==k): return k

        self.__par[k]=self.root(self.__par[k])

        return self.__par[k]



    def unite(self,i,j):

        i=self.root(i); j=self.root(j)

        par=self.__par; rank=self.__rank; size=self.__size

        if(i==j): return False

        if(rank[i]>rank[j]):

            par[j]=i

            size[i]+=size[j]

        else:

            par[i]=j

            size[j]+=size[i]

            if(rank[i]==rank[j]): rank[j]+=1

        self.__connected-=1

        return True



    def size(self,k):

        return self.__size[self.root(k)]



    def connected(self):

        return self.__connected



def resolve():

    n,m=list(map(int,input().split()))

    uf=UnionFind(n)

    for _ in range(m):

        x,y,z=list(map(int,input().split()))

        x-=1; y-=1

        uf.unite(x,y)

    print((uf.connected()))

resolve()
import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

input=lambda:sys.stdin.readline().rstrip()

def resolve():

    n,m=list(map(int,input().split()))

    E=[[] for _ in range(n)]

    for _ in range(m):

        x,y,z=list(map(int,input().split()))

        x-=1; y-=1

        E[x].append(y)

        E[y].append(x)



    cnt=0

    col=[None]*n

    def dfs(v)->bool:

        if(col[v] is not None): return False

        Q=[v]

        col[v]=cnt

        while(Q):

            v=Q.pop()

            for nv in E[v]:

                if(col[nv] is not None): continue

                col[nv]=cnt

                Q.append(nv)

        return True



    for v in range(n):

        cnt+=dfs(v)



    print(cnt)

resolve()
import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
input = lambda: sys.stdin.readline().rstrip()


class UnionFind(object):
    def __init__(self, n):
        self.__par = list(range(n))
        self.__rank = [0] * n
        self.__size = [1] * n
        self.__connected = n

    def root(self, k):
        if self.__par[k] == k:
            return k
        self.__par[k] = self.root(self.__par[k])
        return self.__par[k]

    def unite(self, i, j):
        i = self.root(i)
        j = self.root(j)
        par = self.__par
        rank = self.__rank
        size = self.__size
        if i == j:
            return False
        if rank[i] > rank[j]:
            par[j] = i
            size[i] += size[j]
        else:
            par[i] = j
            size[j] += size[i]
            if rank[i] == rank[j]:
                rank[j] += 1
        self.__connected -= 1
        return True

    def size(self, k):
        return self.__size[self.root(k)]

    def connected(self):
        return self.__connected


def resolve():
    n, m = list(map(int, input().split()))
    uf = UnionFind(n)
    for _ in range(m):
        x, y, z = list(map(int, input().split()))
        x -= 1
        y -= 1
        uf.unite(x, y)
    print((uf.connected()))


resolve()

import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
input = lambda: sys.stdin.readline().rstrip()


def resolve():
    n, m = list(map(int, input().split()))
    E = [[] for _ in range(n)]
    for _ in range(m):
        x, y, z = list(map(int, input().split()))
        x -= 1
        y -= 1
        E[x].append(y)
        E[y].append(x)
    cnt = 0
    col = [None] * n

    def dfs(v) -> bool:
        if col[v] is not None:
            return False
        Q = [v]
        col[v] = cnt
        while Q:
            v = Q.pop()
            for nv in E[v]:
                if col[nv] is not None:
                    continue
                col[nv] = cnt
                Q.append(nv)
        return True

    for v in range(n):
        cnt += dfs(v)
    print(cnt)


resolve()

-class UnionFind(object): -    def __init__(self, n): -        self.__par = list(range(n)) -        self.__rank = [0] * n -        self.__size = [1] * n -        self.__connected = n - -    def root(self, k): -        if self.__par[k] == k: -            return k -        self.__par[k] = self.root(self.__par[k]) -        return self.__par[k] - -    def unite(self, i, j): -        i = self.root(i) -        j = self.root(j) -        par = self.__par -        rank = self.__rank -        size = self.__size -        if i == j: -            return False -        if rank[i] > rank[j]: -            par[j] = i -            size[i] += size[j] -        else: -            par[i] = j -            size[j] += size[i] -            if rank[i] == rank[j]: -                rank[j] += 1 -        self.__connected -= 1 -        return True - -    def size(self, k): -        return self.__size[self.root(k)] - -    def connected(self): -        return self.__connected - - -    uf = UnionFind(n) +    E = [[] for _ in range(n)] -        uf.unite(x, y) -    print((uf.connected())) +        E[x].append(y) +        E[y].append(x) +    cnt = 0 +    col = [None] * n + +    def dfs(v) -> bool: +        if col[v] is not None: +            return False +        Q = [v] +        col[v] = cnt +        while Q: +            v = Q.pop() +            for nv in E[v]: +                if col[nv] is not None: +                    continue +                col[nv] = cnt +                Q.append(nv) +        return True + +    for v in range(n): +        cnt += dfs(v) +    print(cnt)