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

# parent(親)
par = [i for i in range(N+1)]
# rank(深さ)
rank = [0 for i in range(N+1)]
# 同グループの頂点数
size = [1 for i in range(N+1)]

# 木の根を求める
def root(x):
    if par[x] == x:             # 根の時
        return x
    else:
        par[x] = root(par[x])   # 経路圧縮
        return par[x]

# xとyの属する集合を併合(ランク有)
def unite(x,y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y              # xの親をyに
        size[y] += size[x]      # yの頂点数+=xの頂点数
    else:
        par[y] = x              # yの親をxに
        size[x] += size[y]      # xの頂点数+=yの頂点数
        if rank[x] == rank[y]:
            rank[x] += 1

for _ in range(M):
    x,y,z = map(int,input().split())
    unite(x,y)
ans = 0
for i in range(1,N+1):
    if par[i] == i:
        ans += 1
print(ans) N,M = map(int,input().split()) N map(int,input().split()) map int input().split() ().split () input split M i for i in range(N+1) for i in range(N+1) i range(N+1) range N+1 N 1 for i in range(N+1) i par = [i for i in range(N+1)] par [i for i in range(N+1)] 0 for i in range(N+1) for i in range(N+1) i range(N+1) range N+1 N 1 for i in range(N+1) 0 rank = [0 for i in range(N+1)] rank [0 for i in range(N+1)] 1 for i in range(N+1) for i in range(N+1) i range(N+1) range N+1 N 1 for i in range(N+1) 1 size = [1 for i in range(N+1)] size [1 for i in range(N+1)] def root(x):
    if par[x] == x:             # 根の時
        return x
    else:
        par[x] = root(par[x])   # 経路圧縮
        return par[x]

# xとyの属する集合を併合(ランク有) root if par[x] == x:             # 根の時
        return x
    else:
        par[x] = root(par[x])   # 経路圧縮
        return par[x]

# xとyの属する集合を併合(ランク有) par[x] == x par[x] par x x return x x par[x] = root(par[x]) par[x] par x root(par[x]) root par[x] par x return par[x] par[x] par x x x def unite(x,y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y              # xの親をyに
        size[y] += size[x]      # yの頂点数+=xの頂点数
    else:
        par[y] = x              # yの親をxに
        size[x] += size[y]      # xの頂点数+=yの頂点数
        if rank[x] == rank[y]:
            rank[x] += 1 unite x = root(x) x root(x) root x y = root(y) y root(y) root y if x == y:
        return
     x == y x y return if rank[x] < rank[y]:
        par[x] = y              # xの親をyに
        size[y] += size[x]      # yの頂点数+=xの頂点数
    else:
        par[y] = x              # yの親をxに
        size[x] += size[y]      # xの頂点数+=yの頂点数
        if rank[x] == rank[y]:
            rank[x] += 1 rank[x] < rank[y] rank[x] rank x rank[y] rank y par[x] = y par[x] par x y size[y] += size[x] size[y] size y size[x] size x par[y] = x par[y] par y x size[x] += size[y] size[x] size x size[y] size y if rank[x] == rank[y]:
            rank[x] += 1 rank[x] == rank[y] rank[x] rank x rank[y] rank y rank[x] += 1 rank[x] rank x 1 x x y y for _ in range(M):
    x,y,z = map(int,input().split())
    unite(x,y) _ range(M) range M x,y,z = map(int,input().split()) x map(int,input().split()) map int input().split() ().split () input split y z unite(x,y) unite x y ans = 0 ans 0 for i in range(1,N+1):
    if par[i] == i:
        ans += 1 i range(1,N+1) range 1 N+1 N 1 if par[i] == i:
        ans += 1 par[i] == i par[i] par i i ans += 1 ans 1 print(ans) print ans N,M = map(int,input().split()) map(int,input().split()) N M = map(int,input().split()) map(int,input().split()) M x,y,z = map(int,input().split()) map(int,input().split()) x z = map(int,input().split()) map(int,input().split()) z par = [i for i in range(N+1)] [i for i in range(N+1)] par ans = 0 0 ans rank = [0 for i in range(N+1)] [0 for i in range(N+1)] rank def root(x):
    if par[x] == x:             # 根の時
        return x
    else:
        par[x] = root(par[x])   # 経路圧縮
        return par[x]

# xとyの属する集合を併合(ランク有) def root(x):
    if par[x] == x:             # 根の時
        return x
    else:
        par[x] = root(par[x])   # 経路圧縮
        return par[x]

# xとyの属する集合を併合(ランク有) root size = [1 for i in range(N+1)] [1 for i in range(N+1)] size def unite(x,y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y              # xの親をyに
        size[y] += size[x]      # yの頂点数+=xの頂点数
    else:
        par[y] = x              # yの親をxに
        size[x] += size[y]      # xの頂点数+=yの頂点数
        if rank[x] == rank[y]:
            rank[x] += 1 def unite(x,y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y              # xの親をyに
        size[y] += size[x]      # yの頂点数+=xの頂点数
    else:
        par[y] = x              # yの親をxに
        size[x] += size[y]      # xの頂点数+=yの頂点数
        if rank[x] == rank[y]:
            rank[x] += 1 unite y,z = map(int,input().split()) map(int,input().split()) y ans += 1 1 ans
N,M = map(int,input().split())

# parent(親)
par = [i for i in range(N+1)]
# rank(深さ)
rank = [0 for i in range(N+1)]
# 同グループの頂点数
size = [1 for i in range(N+1)]

# 木の根を求める
def root(x):
    if par[x] == x:             # 根の時
        return x
    else:
        par[x] = root(par[x])   # 経路圧縮
        return par[x]

# xとyの属する集合を併合(ランク有)
def unite(x,y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y              # xの親をyに
        size[y] += size[x]      # yの頂点数+=xの頂点数
    else:
        par[y] = x              # yの親をxに
        size[x] += size[y]      # xの頂点数+=yの頂点数
        if rank[x] == rank[y]:
            rank[x] += 1

for _ in range(M):
    x,y,z = map(int,input().split())
    unite(x,y)
ans = 0
for i in range(1,N+1):
    if par[i] == i:
        ans += 1
print(ans)