Buggy python submission (verdict: Runtime Error):
import sys
sys.setrecursionlimit(10 ** 5)

input = sys.stdin.readline()

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

ans = list(range(N))
def root(a):
    if a==ans[a]:
        return a
    else:
        return root(ans[a])

for _ in range(M):
    x, y, _ = map(lambda a: int(a)-1, input().split())
    if root(x) != root(y):
        rx = root(x)
        ry = root(y)
        while y != ry:
            ans[y], y = rx, ans[y]
        ans[ry] = rx

A = {}
for a in ans:
    A[a] = 1

print(len(A))


Fixed submission:
import sys
sys.setrecursionlimit(10 ** 5)

class UniteFind:
    def __init__(self, N):
        self.par = [i for i in range(N)]

    def root(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        if rx == ry:
            return
        self.par[ry] = rx

    def same(self, x, y):
        if (self.root(x) == self.root(y)):
            return True
        return False


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

for _ in range(M):
    x, y, _ = map(int, input().split())
    rf.unite(x-1, y-1)

m = {i: -1 for i in range(N)}
ans = 0

for i in range(N):
    if m[rf.root(i)] == -1:
        m[rf.root(i)] = 1
        ans += 1

print(ans)

Buggy python submission (verdict: Runtime Error):
class UniteFind:
    def __init__(self, N):
        self.par = [i for i in range(N)]

    def root(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        if rx == ry:
            return
        self.par[ry] = rx

    def same(self, x, y):
        if (self.root(x) == self.root(y)):
            return True
        return False


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

for _ in range(M):
    x, y, _ = map(int, input().split())
    rf.unite(x-1, y-1)

m = {i: -1 for i in range(N)}
ans = 0

for i in range(N):
    if m[rf.root(i)] == -1:
        m[rf.root(i)] = 1
        ans += 1

print(ans)


Fixed submission:
import sys
sys.setrecursionlimit(10 ** 5)

class UniteFind:
    def __init__(self, N):
        self.par = [i for i in range(N)]

    def root(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        if rx == ry:
            return
        self.par[ry] = rx

    def same(self, x, y):
        if (self.root(x) == self.root(y)):
            return True
        return False


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

for _ in range(M):
    x, y, _ = map(int, input().split())
    rf.unite(x-1, y-1)

m = {i: -1 for i in range(N)}
ans = 0

for i in range(N):
    if m[rf.root(i)] == -1:
        m[rf.root(i)] = 1
        ans += 1

print(ans)

Buggy python submission (verdict: Runtime Error):
class UniteFind:
    def __init__(self, N):
        self.par = [i for i in range(N)]

    def root(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        if rx == ry:
            return
        self.par[ry] = rx

    def same(self, x, y):
        if (self.root(x) == self.root(y)):
            return True
        return False


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

for _ in range(M):
    x, y, _ = map(int, input().split())
    rf.unite(x-1, y-1)

m = {i: -1 for i in range(N)}
ans = 0

for i in range(N):
    if m[rf.root(i)] == -1:
        m[rf.root(i)] = 1
        ans += 1

print(ans)


Fixed submission:
import sys
sys.setrecursionlimit(10 ** 5)

class UniteFind:
    def __init__(self, N):
        self.par = [i for i in range(N)]

    def root(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        if rx == ry:
            return
        self.par[ry] = rx

    def same(self, x, y):
        if (self.root(x) == self.root(y)):
            return True
        return False


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

for _ in range(M):
    x, y, _ = map(int, input().split())
    rf.unite(x-1, y-1)

m = {i: -1 for i in range(N)}
ans = 0

for i in range(N):
    if m[rf.root(i)] == -1:
        m[rf.root(i)] = 1
        ans += 1

print(ans)