import sys

input = sys.stdin.readline



#########

class UnionFind():

    """

    parents : 親要素(findしない場合は根ではないことの注意)，根の場合は"-(要素数）"

    find(x):要素xの属するグループの根を返す

    size(x):要素xの属するグループの要素数を返す

    same(x,y):x,yが同じグループに属しているか返す

    members(x):要素xが属するグループに属する要素をリストで返す

    roots(x):全ての根の要素を返す

    group_counte():グループの数を返す

    all_group_members():{根要素：[そのグループに含まれる要素のリスト]}の辞書を返す

    """

    def __init__(self, n):

        self.n = n

        self.parents = [-1] * n



    def find(self, x):

        if self.parents[x] < 0:

            return x

        else:

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

            return self.parents[x]



    def union(self, x, y):

        x = self.find(x)

        y = self.find(y)



        if x == y:

            return



        if self.parents[x] > self.parents[y]:

            x, y = y, x



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

        self.parents[y] = x



    def size(self, x):

        return -self.parents[self.find(x)]



    def same(self, x, y):

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



    def members(self, x):

        root = self.find(x)

        return [i for i in range(self.n) if self.find(i) == root]



    def roots(self):

        return [i for i, x in enumerate(self.parents) if x < 0]



    def group_count(self):

        return len(self.roots())



    def all_group_members(self):

        return {r: self.members(r) for r in self.roots()}



    

def Kruskal(V,edges):

        """

        V:node数

        edges:[u,v,cost]の辺のリスト

        

        return: 最小全域木のコストの和

        """

        #edges = sorted(edges, key=lambda x: x[2])  # costでself.edgesをソートする

        res = 0

        uf=UnionFind(V)

        for e in edges:

            if not uf.same(e[0], e[1]):

                uf.union(e[0], e[1])

                res += e[2]

        return res



############



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

edges=[]



for i in range(M):

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

    edges.append((x-1,y-1,1))

    

E=Kruskal(N,edges)

print((N-E))









import sys

input = sys.stdin.readline



def I(): return int(eval(input()))

def MI(): return list(map(int, input().split()))

def LI(): return list(map(int, input().split()))



def main():

    ################

    class UnionFind():

        """

        parents : 親要素(findしない場合は根ではないことの注意)，根の場合は"-(要素数）"

        find(x):要素xの属するグループの根を返す

        size(x):要素xの属するグループの要素数を返す

        same(x,y):x,yが同じグループに属しているか返す

        重いかも！　　members(x):要素xが属するグループに属する要素をリストで返す

        roots:全ての根の要素を返す

        group_count():グループの数を返す

        重いかも！　all_group_members():{根要素：[そのグループに含まれる要素のリスト]}の辞書を返す

        """

        def __init__(self, n):

            self.n = n

            self.parents = [-1] * n



        def find(self, x):

            #根を探す&つなぎかえる

            if self.parents[x] < 0:

                return x

            else:

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

                return self.parents[x]



        def union(self, x, y):

            x = self.find(x)

            y = self.find(y)



            if x == y:

                return



            if self.parents[x] > self.parents[y]:

                x, y = y, x



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

            self.parents[y] = x



        def size(self, x):

            return -self.parents[self.find(x)]



        def same(self, x, y):

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



        def members(self, x):

            root = self.find(x)

            return [i for i in range(self.n) if self.find(i) == root]



        def roots(self):

            return [i for i, x in enumerate(self.parents) if x < 0]



        def group_count(self):

            return len(self.roots())



        def all_group_members(self):

            return {r: self.members(r) for r in self.roots()}



        def __str__(self):

            return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

        

    ################





    mod=10**9+7

    N,M=MI()

    uf=UnionFind(N)

    #連結成分の数

    

    for i in range(M):

        x,y,z=MI()

        x-=1

        y-=1

        uf.union(x,y)

        

    print((uf.group_count()))

    

    



main()

import sys

input = sys.stdin.readline
#########
class UnionFind:
    """
    parents : 親要素(findしない場合は根ではないことの注意)，根の場合は"-(要素数）"
    find(x):要素xの属するグループの根を返す
    size(x):要素xの属するグループの要素数を返す
    same(x,y):x,yが同じグループに属しているか返す
    members(x):要素xが属するグループに属する要素をリストで返す
    roots(x):全ての根の要素を返す
    group_counte():グループの数を返す
    all_group_members():{根要素：[そのグループに含まれる要素のリスト]}の辞書を返す
    """

    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

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

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y = y, x
        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

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

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}


def Kruskal(V, edges):
    """
    V:node数
    edges:[u,v,cost]の辺のリスト
    return: 最小全域木のコストの和
    """
    # edges = sorted(edges, key=lambda x: x[2])  # costでself.edgesをソートする
    res = 0
    uf = UnionFind(V)
    for e in edges:
        if not uf.same(e[0], e[1]):
            uf.union(e[0], e[1])
            res += e[2]
    return res


############
N, M = list(map(int, input().split()))
edges = []
for i in range(M):
    x, y, z = list(map(int, input().split()))
    edges.append((x - 1, y - 1, 1))
E = Kruskal(N, edges)
print((N - E))

import sys

input = sys.stdin.readline


def I():
    return int(eval(input()))


def MI():
    return list(map(int, input().split()))


def LI():
    return list(map(int, input().split()))


def main():
    ################
    class UnionFind:
        """
        parents : 親要素(findしない場合は根ではないことの注意)，根の場合は"-(要素数）"
        find(x):要素xの属するグループの根を返す
        size(x):要素xの属するグループの要素数を返す
        same(x,y):x,yが同じグループに属しているか返す
        重いかも！　　members(x):要素xが属するグループに属する要素をリストで返す
        roots:全ての根の要素を返す
        group_count():グループの数を返す
        重いかも！　all_group_members():{根要素：[そのグループに含まれる要素のリスト]}の辞書を返す
        """

        def __init__(self, n):
            self.n = n
            self.parents = [-1] * n

        def find(self, x):
            # 根を探す&つなぎかえる
            if self.parents[x] < 0:
                return x
            else:
                self.parents[x] = self.find(self.parents[x])
                return self.parents[x]

        def union(self, x, y):
            x = self.find(x)
            y = self.find(y)
            if x == y:
                return
            if self.parents[x] > self.parents[y]:
                x, y = y, x
            self.parents[x] += self.parents[y]
            self.parents[y] = x

        def size(self, x):
            return -self.parents[self.find(x)]

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

        def members(self, x):
            root = self.find(x)
            return [i for i in range(self.n) if self.find(i) == root]

        def roots(self):
            return [i for i, x in enumerate(self.parents) if x < 0]

        def group_count(self):
            return len(self.roots())

        def all_group_members(self):
            return {r: self.members(r) for r in self.roots()}

        def __str__(self):
            return "\n".join("{}: {}".format(r, self.members(r)) for r in self.roots())

    ################
    mod = 10**9 + 7
    N, M = MI()
    uf = UnionFind(N)
    # 連結成分の数
    for i in range(M):
        x, y, z = MI()
        x -= 1
        y -= 1
        uf.union(x, y)
    print((uf.group_count()))


main()

-######### -class UnionFind: -    """ -    parents : 親要素(findしない場合は根ではないことの注意)，根の場合は"-(要素数）" -    find(x):要素xの属するグループの根を返す -    size(x):要素xの属するグループの要素数を返す -    same(x,y):x,yが同じグループに属しているか返す -    members(x):要素xが属するグループに属する要素をリストで返す -    roots(x):全ての根の要素を返す -    group_counte():グループの数を返す -    all_group_members():{根要素：[そのグループに含まれる要素のリスト]}の辞書を返す -    """ - -    def __init__(self, n): -        self.n = n -        self.parents = [-1] * n - -    def find(self, x): -        if self.parents[x] < 0: -            return x -        else: -            self.parents[x] = self.find(self.parents[x]) -            return self.parents[x] - -    def union(self, x, y): -        x = self.find(x) -        y = self.find(y) -        if x == y: -            return -        if self.parents[x] > self.parents[y]: -            x, y = y, x -        self.parents[x] += self.parents[y] -        self.parents[y] = x - -    def size(self, x): -        return -self.parents[self.find(x)] - -    def same(self, x, y): -        return self.find(x) == self.find(y) - -    def members(self, x): -        root = self.find(x) -        return [i for i in range(self.n) if self.find(i) == root] - -    def roots(self): -        return [i for i, x in enumerate(self.parents) if x < 0] - -    def group_count(self): -        return len(self.roots()) - -    def all_group_members(self): -        return {r: self.members(r) for r in self.roots()} -def Kruskal(V, edges): -    """ -    V:node数 -    edges:[u,v,cost]の辺のリスト -    return: 最小全域木のコストの和 -    """ -    # edges = sorted(edges, key=lambda x: x[2])  # costでself.edgesをソートする -    res = 0 -    uf = UnionFind(V) -    for e in edges: -        if not uf.same(e[0], e[1]): -            uf.union(e[0], e[1]) -            res += e[2] -    return res +def I(): +    return int(eval(input())) -############ -N, M = list(map(int, input().split())) -edges = [] -for i in range(M): -    x, y, z = list(map(int, input().split())) -    edges.append((x - 1, y - 1, 1)) -E = Kruskal(N, edges) -print((N - E)) +def MI(): +    return list(map(int, input().split())) + + +def LI(): +    return list(map(int, input().split())) + + +def main(): +    ################ +    class UnionFind: +        """ +        parents : 親要素(findしない場合は根ではないことの注意)，根の場合は"-(要素数）" +        find(x):要素xの属するグループの根を返す +        size(x):要素xの属するグループの要素数を返す +        same(x,y):x,yが同じグループに属しているか返す +        重いかも！　　members(x):要素xが属するグループに属する要素をリストで返す +        roots:全ての根の要素を返す +        group_count():グループの数を返す +        重いかも！　all_group_members():{根要素：[そのグループに含まれる要素のリスト]}の辞書を返す +        """ + +        def __init__(self, n): +            self.n = n +            self.parents = [-1] * n + +        def find(self, x): +            # 根を探す&つなぎかえる +            if self.parents[x] < 0: +                return x +            else: +                self.parents[x] = self.find(self.parents[x]) +                return self.parents[x] + +        def union(self, x, y): +            x = self.find(x) +            y = self.find(y) +            if x == y: +                return +            if self.parents[x] > self.parents[y]: +                x, y = y, x +            self.parents[x] += self.parents[y] +            self.parents[y] = x + +        def size(self, x): +            return -self.parents[self.find(x)] + +        def same(self, x, y): +            return self.find(x) == self.find(y) + +        def members(self, x): +            root = self.find(x) +            return [i for i in range(self.n) if self.find(i) == root] + +        def roots(self): +            return [i for i, x in enumerate(self.parents) if x < 0] + +        def group_count(self): +            return len(self.roots()) + +        def all_group_members(self): +            return {r: self.members(r) for r in self.roots()} + +        def __str__(self): +            return "\n".join("{}: {}".format(r, self.members(r)) for r in self.roots()) + +    ################ +    mod = 10**9 + 7 +    N, M = MI() +    uf = UnionFind(N) +    # 連結成分の数 +    for i in range(M): +        x, y, z = MI() +        x -= 1 +        y -= 1 +        uf.union(x, y) +    print((uf.group_count())) + + +main()