Buggy python submission (verdict: Runtime Error):
N,M=map(int,input().split())

class UnionFind:
  def __init__(self, n):
    self.n = n
    self.parents = [i for i in range(n)]
 
  def find(self, x):
    if self.parents[x]==x:
      return x
    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.size(x) < self.size(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 cnt(self):
    par=self.parents
    return len(set(par))

uf=UnionFind(N)
for i in range(M):
  x,y,z=map(int,input().split())
  uf.union(x-1,y-1)
print(uf.cnt())

Fixed submission:
class UnionFind:
    def __init__(self, n):
        self.n = n
        self.p = [e for e in range(n)]
        self.rank = [0] * n
        self.size = [1] * n

    def same(self, u, v):
        return self.find_set(u) == self.find_set(v)

    def unite(self, u, v):
        u = self.find_set(u)
        v = self.find_set(v)

        if u == v:
            return

        if self.rank[u] > self.rank[v]:
            self.p[v] = u
            self.size[u] += self.size[v]
        else:
            self.p[u] = v
            self.size[v] += self.size[u]
            if self.rank[u] == self.rank[v]:
                self.rank[v] += 1

    def find_set(self, u):
        if u != self.p[u]:
            self.p[u] = self.find_set(self.p[u])

        return self.p[u]

    def update_p(self):
        for u in range(self.n):
            self.find_set(u)

    def get_size(self, u):
        return self.size[self.find_set(u)]


n, m = map(int, input().split())
xyz = [list(map(int, input().split())) for _ in range(m)]

uf = UnionFind(n)

for x, y, _ in xyz:
    x -= 1
    y -= 1
    uf.unite(x, y)

uf.update_p()
ans = len(set(uf.p))
print(ans)

Buggy python submission (verdict: Time Limit Exceeded):
N,M=map(int,input().split())

class UnionFind():
  def __init__(self,n):
    self.parent={}
    for i in range(n):
      self.parent[i]=[i]
      
  def find_parent(self,x):
    import sys
    parent=self.parent
    for key in parent.keys():
      if x in parent[key]:
        return key
        sys.exit()
        
  def union(self,x,y):
    parent=self.parent
    x_par,y_par=self.find_parent(x),self.find_parent(y)
    if x_par==y_par:
      pass
    else:
      if len(parent[x_par])<len(parent[y_par]):
        parent[y_par]+=parent[x_par]
        parent.pop(x_par)
      else:
        parent[x_par]+=parent[y_par]
        parent.pop(y_par)
    self.parent=parent
    return None
  
  def same(self,x,y):
    if self.find_parent(x)==self.find_parent(y):
      return True
    else:
      return False
  def cnt(self):
    par=self.parent
    return len(set(par))
uf=UnionFind(N)
for i in range(M):
  x,y,z=map(int,input().split())
  uf.union(x-1,y-1)
print(uf.cnt())

Fixed submission:
class UnionFind:
    def __init__(self, n):
        self.n = n
        self.p = [e for e in range(n)]
        self.rank = [0] * n
        self.size = [1] * n

    def same(self, u, v):
        return self.find_set(u) == self.find_set(v)

    def unite(self, u, v):
        u = self.find_set(u)
        v = self.find_set(v)

        if u == v:
            return

        if self.rank[u] > self.rank[v]:
            self.p[v] = u
            self.size[u] += self.size[v]
        else:
            self.p[u] = v
            self.size[v] += self.size[u]
            if self.rank[u] == self.rank[v]:
                self.rank[v] += 1

    def find_set(self, u):
        if u != self.p[u]:
            self.p[u] = self.find_set(self.p[u])

        return self.p[u]

    def update_p(self):
        for u in range(self.n):
            self.find_set(u)

    def get_size(self, u):
        return self.size[self.find_set(u)]


n, m = map(int, input().split())
xyz = [list(map(int, input().split())) for _ in range(m)]

uf = UnionFind(n)

for x, y, _ in xyz:
    x -= 1
    y -= 1
    uf.unite(x, y)

uf.update_p()
ans = len(set(uf.p))
print(ans)