Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10 ** 6)

def dfs(n):
    # print('Search Start: ' + str(n))
    if checked[n]:
        # print('Checked: ' + str(n))
        return
    checked[n] = True
    for e in edge:
        if n in e:
            x, y = e
            if n != x:
                dfs(x)
            else:
                dfs(y)
    # print('Search End: ' + str(n))

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

edge = [] * M
checked = [False for _ in range(N)]

con_com = 0

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

for i in range(N):
    if checked[i]:
        continue
    dfs(i)
    # print('--- Connected Components ---')
    con_com += 1

print(con_com)


Fixed submission:
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10 ** 6)

class UnionFind(object):
    def __init__(self, n):
        self.parent = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]
        self.size = [1 for _ in range(n)]
        self.components = n

    def find(self, x):
        if self.parent[x] == x:
            return x
        self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            elif self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.parent[y] = x
            self.size[x] += self.size[y]
            self.components -= 1

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

    def getSize(self, x):
        return self.size(self.find(x))

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

edge = [] * M
uf = UnionFind(N)

for _ in range(M):
    x, y, _ = list(map(int, input().split()))
    uf.union(x-1, y-1)

print(uf.components)

Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-

from collections import deque
import sys
sys.setrecursionlimit(10 ** 6)

def dfs(n):
    # print('Search Start: ' + str(n))
    # print(graph)
    stack1 = graph[n]
    while stack1:
        x = stack1.popleft()
        dfs(x)
    for i in range(N):
        if n in graph[i]:
            dfs(i)
    checked[n] = True
    # print('Search End: ' + str(n))

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

graph = {i: deque() for i in range(N)}
checked = [False for _ in range(N)]

con_com = 0

for _ in range(M):
    x, y, _ = list(map(int, input().split()))
    graph[min(x, y)-1].append(max(x, y)-1)

for i in range(N):
    if checked[i]:
        continue
    dfs(i)
    # print('--- Connected Components ---')
    con_com += 1

print(con_com)


Fixed submission:
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10 ** 6)

class UnionFind(object):
    def __init__(self, n):
        self.parent = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]
        self.size = [1 for _ in range(n)]
        self.components = n

    def find(self, x):
        if self.parent[x] == x:
            return x
        self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            elif self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.parent[y] = x
            self.size[x] += self.size[y]
            self.components -= 1

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

    def getSize(self, x):
        return self.size(self.find(x))

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

edge = [] * M
uf = UnionFind(N)

for _ in range(M):
    x, y, _ = list(map(int, input().split()))
    uf.union(x-1, y-1)

print(uf.components)

Buggy python submission (verdict: Time Limit Exceeded):
# -*- coding: utf-8 -*-

from collections import deque
import sys
sys.setrecursionlimit(10 ** 6)

def dfs(n):
    # print('Search Start: ' + str(n))
    # print(graph)
    stack1 = graph[n]
    while stack1:
        x = stack1.popleft()
        dfs(x)
    for i in range(N):
        if n in graph[i]:
            dfs(i)
    checked[n] = True
    # print('Search End: ' + str(n))

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

graph = {i: deque() for i in range(N)}
checked = [False for _ in range(N)]

con_com = 0

for _ in range(M):
    x, y, _ = list(map(int, input().split()))
    graph[min(x, y)-1].append(max(x, y)-1)

for i in range(N):
    if checked[i]:
        continue
    dfs(i)
    # print('--- Connected Components ---')
    con_com += 1

print(con_com)


Fixed submission:
# -*- coding: utf-8 -*-

import sys
sys.setrecursionlimit(10 ** 6)

class UnionFind(object):
    def __init__(self, n):
        self.parent = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]
        self.size = [1 for _ in range(n)]
        self.components = n

    def find(self, x):
        if self.parent[x] == x:
            return x
        self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            elif self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.parent[y] = x
            self.size[x] += self.size[y]
            self.components -= 1

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

    def getSize(self, x):
        return self.size(self.find(x))

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

edge = [] * M
uf = UnionFind(N)

for _ in range(M):
    x, y, _ = list(map(int, input().split()))
    uf.union(x-1, y-1)

print(uf.components)