Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10**7)
input = sys.stdin.readline
def main():
    N,M = map(int,input().split())
    G = [[] for _ in range(N+1)]
    
    for _ in range(M):
        x,y,z = map(int,input().split())
        x -= 1
        y -= 1
        G[x].append(y)
        G[y].append(x)
    
    seen = [False]*(N)
    ans = 0
    def dfs(v):
        if seen[v]:
            return
        seen[v] = True
        for nv in G[v]:
            dfs(nv)
    
    for v in range(N):
        if not seen[v]:
            dfs(v)
            ans += 1
    print(ans)

if __name__ == '__main__':
    main()

Fixed submission:
N,M = map(int,input().split())

par = [-1]*(N+1)


def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]


def unite(x,y):
    x = find(x)
    y = find(y)
    if x == y:
        return False
    else:
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True


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


def size(x):
    return -par[find(x)]

for i in range(M):
    x,y,z = map(int,input().split())
    unite(x,y)

ans = 0
counted = [False] * (N+1)
for i in range(1,N+1):
    root = find(i)
    if not counted[root]:
        ans += 1
        counted[root] = True
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10**7)
input = sys.stdin.readline
N,M = map(int,input().split())
G = [[] for _ in range(N+1)]

for _ in range(M):
    x,y,z = map(int,input().split())
    x -= 1
    y -= 1
    G[x].append(y)
    G[y].append(x)

seen = [False]*(N)
ans = 0
def dfs(v):
    if seen[v]:
        return
    seen[v] = True
    for nv in G[v]:
        dfs(nv)

for v in range(N):
    if not seen[v]:
        dfs(v)
        ans += 1
print(ans)

Fixed submission:
N,M = map(int,input().split())

par = [-1]*(N+1)


def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]


def unite(x,y):
    x = find(x)
    y = find(y)
    if x == y:
        return False
    else:
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True


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


def size(x):
    return -par[find(x)]

for i in range(M):
    x,y,z = map(int,input().split())
    unite(x,y)

ans = 0
counted = [False] * (N+1)
for i in range(1,N+1):
    root = find(i)
    if not counted[root]:
        ans += 1
        counted[root] = True
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
import sys
sys.setrecursionlimit(10**7)
N,M = map(int,input().split())
G = [[] for _ in range(N)]

for _ in range(M):
    x,y,z = map(int,input().split())
    x -= 1
    y -= 1
    G[x].append(y)
    G[y].append(x)

seen = [False]*(N)
ans = 0
def dfs(v):
    if seen[v]:
        return
    seen[v] = True
    for nv in G[v]:
        dfs(nv)

for v in range(N):
    if not seen[v]:
        dfs(v)
        ans += 1
print(ans)

Fixed submission:
N,M = map(int,input().split())

par = [-1]*(N+1)


def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]


def unite(x,y):
    x = find(x)
    y = find(y)
    if x == y:
        return False
    else:
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True


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


def size(x):
    return -par[find(x)]

for i in range(M):
    x,y,z = map(int,input().split())
    unite(x,y)

ans = 0
counted = [False] * (N+1)
for i in range(1,N+1):
    root = find(i)
    if not counted[root]:
        ans += 1
        counted[root] = True
print(ans)

Buggy python submission (verdict: Runtime Error):
N,M = map(int,input().split())
G = [[] for _ in range(N)]

for _ in range(M):
    x,y,z = map(int,input().split())
    x -= 1
    y -= 1
    G[x].append(y)
    G[y].append(x)

seen = [False]*(N)
ans = 0
def dfs(v):
    if seen[v]:
        return
    seen[v] = True
    for nv in G[v]:
        dfs(nv)

for v in range(N):
    if not seen[v]:
        dfs(v)
        ans += 1
print(ans)

Fixed submission:
N,M = map(int,input().split())

par = [-1]*(N+1)


def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]


def unite(x,y):
    x = find(x)
    y = find(y)
    if x == y:
        return False
    else:
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True


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


def size(x):
    return -par[find(x)]

for i in range(M):
    x,y,z = map(int,input().split())
    unite(x,y)

ans = 0
counted = [False] * (N+1)
for i in range(1,N+1):
    root = find(i)
    if not counted[root]:
        ans += 1
        counted[root] = True
print(ans)