class UnionFind:

    def __init__(self, n):

        self.v = [-1 for _ in range(n)]  # 根(負): 連結頂点数 * (-1) / 子(正): 根の頂点番号(0-indexed)



    def find(self, x):  # xを含む木における根の頂点番号を返す

        if self.v[x] < 0:  # (負)は根

            return x

        else:  # 根の頂点番号

            self.v[x] = self.find(self.v[x])  # uniteでは, 旧根に属する頂点の根が旧根のままなので更新

            return self.v[x]



    def unite(self, x, y):  # 違う根に属していたらrankが低くなるように連結

        x = self.find(x)

        y = self.find(y)

        if x == y:

            return

        if -self.v[x] < -self.v[y]:  # size比較, 　(-1) * (連結頂点数 * (-1)), (正)同士の大小比較

            x, y = y, x  # 連結頂点数が少ない方をyにすると, findでの更新回数が減る？

        self.v[x] += self.v[y]  # 連結頂点数の和を取る, 連結頂点数 * (-1)

        self.v[y] = x  # 連結頂点数が少ないy(引数yの根の頂点番号)の根をx(引数xの根の頂点番号)にする



    def root(self, x):

        return self.v[x] < 0  # (負)は根



    def same(self, x, y):

        return self.find(x) == self.find(y)  # 同じ根に属するか



    def size(self, x):

        return -self.v[self.find(x)]  # 連結頂点数を返す





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

uf = UnionFind(N * 2)

for _ in range(M):

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

    x -= 1

    y -= 1

    if z % 2 == 0:

        uf.unite(x, y)

        uf.unite(x + N, y + N)

    else:

        uf.unite(x, y + N)

        uf.unite(x + N, y)



# print(uf.v)



ans = 0

for i in range(N):

    if uf.root(i):

        ans += 1

print(ans)

class UnionFind:

    def __init__(self, n):

        self.v = [-1 for _ in range(n)]



    def find(self, x):

        if self.v[x] < 0:

            return x

        else:

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

            return self.v[x]



    def unite(self, x, y):

        x = self.find(x)

        y = self.find(y)

        if x == y:

            return

        if -self.v[x] < -self.v[y]:

            x, y = y, x

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

        self.v[y] = x



    def root(self, x):

        return self.v[x] < 0



    def same(self, x, y):

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



    def size(self, x):

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





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

uf = UnionFind(N * 2)

for _ in range(M):

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

    x -= 1

    y -= 1



    if z & 1:

        uf.unite(x + N, y)

        uf.unite(x, y + N)

    else:

        uf.unite(x, y)

        uf.unite(x + N, y + N)

print((sum(1 for i in range(N) if uf.root(i))))

class UnionFind:
    def __init__(self, n):
        self.v = [-1 for _ in range(n)]  # 根(負): 連結頂点数 * (-1) / 子(正): 根の頂点番号(0-indexed)

    def find(self, x):  # xを含む木における根の頂点番号を返す
        if self.v[x] < 0:  # (負)は根
            return x
        else:  # 根の頂点番号
            self.v[x] = self.find(self.v[x])  # uniteでは, 旧根に属する頂点の根が旧根のままなので更新
            return self.v[x]

    def unite(self, x, y):  # 違う根に属していたらrankが低くなるように連結
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if -self.v[x] < -self.v[y]:  # size比較, 　(-1) * (連結頂点数 * (-1)), (正)同士の大小比較
            x, y = y, x  # 連結頂点数が少ない方をyにすると, findでの更新回数が減る？
        self.v[x] += self.v[y]  # 連結頂点数の和を取る, 連結頂点数 * (-1)
        self.v[y] = x  # 連結頂点数が少ないy(引数yの根の頂点番号)の根をx(引数xの根の頂点番号)にする

    def root(self, x):
        return self.v[x] < 0  # (負)は根

    def same(self, x, y):
        return self.find(x) == self.find(y)  # 同じ根に属するか

    def size(self, x):
        return -self.v[self.find(x)]  # 連結頂点数を返す


N, M = list(map(int, input().split()))
uf = UnionFind(N * 2)
for _ in range(M):
    x, y, z = list(map(int, input().split()))
    x -= 1
    y -= 1
    if z % 2 == 0:
        uf.unite(x, y)
        uf.unite(x + N, y + N)
    else:
        uf.unite(x, y + N)
        uf.unite(x + N, y)
# print(uf.v)
ans = 0
for i in range(N):
    if uf.root(i):
        ans += 1
print(ans)

class UnionFind:
    def __init__(self, n):
        self.v = [-1 for _ in range(n)]

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

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if -self.v[x] < -self.v[y]:
            x, y = y, x
        self.v[x] += self.v[y]
        self.v[y] = x

    def root(self, x):
        return self.v[x] < 0

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

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


N, M = list(map(int, input().split()))
uf = UnionFind(N * 2)
for _ in range(M):
    x, y, z = list(map(int, input().split()))
    x -= 1
    y -= 1
    if z & 1:
        uf.unite(x + N, y)
        uf.unite(x, y + N)
    else:
        uf.unite(x, y)
        uf.unite(x + N, y + N)
print((sum(1 for i in range(N) if uf.root(i))))

-        self.v = [-1 for _ in range(n)]  # 根(負): 連結頂点数 * (-1) / 子(正): 根の頂点番号(0-indexed) +        self.v = [-1 for _ in range(n)] -    def find(self, x):  # xを含む木における根の頂点番号を返す -        if self.v[x] < 0:  # (負)は根 +    def find(self, x): +        if self.v[x] < 0: -        else:  # 根の頂点番号 -            self.v[x] = self.find(self.v[x])  # uniteでは, 旧根に属する頂点の根が旧根のままなので更新 +        else: +            self.v[x] = self.find(self.v[x]) -    def unite(self, x, y):  # 違う根に属していたらrankが低くなるように連結 +    def unite(self, x, y): -        if -self.v[x] < -self.v[y]:  # size比較, 　(-1) * (連結頂点数 * (-1)), (正)同士の大小比較 -            x, y = y, x  # 連結頂点数が少ない方をyにすると, findでの更新回数が減る？ -        self.v[x] += self.v[y]  # 連結頂点数の和を取る, 連結頂点数 * (-1) -        self.v[y] = x  # 連結頂点数が少ないy(引数yの根の頂点番号)の根をx(引数xの根の頂点番号)にする +        if -self.v[x] < -self.v[y]: +            x, y = y, x +        self.v[x] += self.v[y] +        self.v[y] = x -        return self.v[x] < 0  # (負)は根 +        return self.v[x] < 0 -        return self.find(x) == self.find(y)  # 同じ根に属するか +        return self.find(x) == self.find(y) -        return -self.v[self.find(x)]  # 連結頂点数を返す +        return -self.v[self.find(x)] -    if z % 2 == 0: +    if z & 1: +        uf.unite(x + N, y) +        uf.unite(x, y + N) +    else: -    else: -        uf.unite(x, y + N) -        uf.unite(x + N, y) -# print(uf.v) -ans = 0 -for i in range(N): -    if uf.root(i): -        ans += 1 -print(ans) +print((sum(1 for i in range(N) if uf.root(i))))