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

relation = [[] for _ in range(N+1)]

for _ in range(M) :
	X, Y, Z = map(int, input().split())
	relation[X].append(Y)
	relation[Y].append(X)

visited = [False] * (N + 1)

def dfs(init) :
	queue = [init]

	while queue :
		x_ = queue.pop(0)
		visited[x_] = True

		for y_ in relation[x_] :
			if not visited[y_] :
				queue.append(y_)

# 閉路ごとdfs実行
n_closed = 0
for i in range(1, N + 1) :
	if len(relation[i]) and not visited[i] :
		n_closed += 1
		dfs(i)

print(n_closed + visited.count(False) - 1)


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

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

def root(x):
	while parent[x] >= 0:
		x = parent[x]
	return x

def unite(x,y):
	root_x = root(x)
	root_y = root(y)

	if root_x != root_y :
		if parent[root_x] > parent[root_y] :
			parent[root_x]=root_y
		else :
			if parent[root_x] == parent[root_y] :
				parent[root_x] -= 1
			parent[root_y] = root_x
    
	return

for _ in range(M) :
	X, Y, Z = map(int, input().split())
	unite(X, Y)
	
print(sum(i < 0 for i in parent) - 1)

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

relation = [[] for _ in range(N+1)]

for _ in range(M) :
	X, Y, Z = map(int, input().split())
	Z &= 1
	relation[X].append((Y, Z))
	relation[Y].append((X, Z))

visited = [False] * (N + 1)
p = [-1] * (N + 1)

def dfs(init) :
	queue = [init]
	p[init] = 0

	while queue :
		x_ = queue.pop(0)
		visited[x_] = True

		for y_, z_ in relation[x_] :
			if not visited[y_] :
				p[y_] = (z_ & 1) ^ p[x_]
				queue.append(y_)

# 閉路ごとdfs実行
n_closed = 0
for i in range(1, N + 1) :
	if len(relation[i]) and not visited[i] :
		n_closed += 1
		dfs(i)

print(n_closed + visited.count(False) - 1)


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

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

def root(x):
	while parent[x] >= 0:
		x = parent[x]
	return x

def unite(x,y):
	root_x = root(x)
	root_y = root(y)

	if root_x != root_y :
		if parent[root_x] > parent[root_y] :
			parent[root_x]=root_y
		else :
			if parent[root_x] == parent[root_y] :
				parent[root_x] -= 1
			parent[root_y] = root_x
    
	return

for _ in range(M) :
	X, Y, Z = map(int, input().split())
	unite(X, Y)
	
print(sum(i < 0 for i in parent) - 1)

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

relation = [[] for _ in range(N+1)]

for _ in range(M) :
	X, Y, Z = map(int, input().split())
	Z &= 1
	relation[X].append((Y, Z))
	relation[Y].append((X, Z))

visited = [False] * (N + 1)
p = [-1] * (N + 1)

def dfs(init) :
	queue = [init]
	p[init] = 0

	while queue :
		x_ = queue.pop(0)
		visited[x_] = True

		for y_, z_ in relation[x_] :
			if visited[y_] :
				if (z_ & 1) ^ p[x_] != p[y_] :
					return False
			else :
				p[y_] = (z_ & 1) ^ p[x_]
				queue.append(y_)

	return True

def calc() :
	# 閉路ごと実行
	res = 0
	for i in range(1, N + 1) :
		if len(relation[i]) and not visited[i] :
			res += 1
			if not dfs(i) :
				return -1

	return res + visited.count(False) - 1

print(calc())

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

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

def root(x):
	while parent[x] >= 0:
		x = parent[x]
	return x

def unite(x,y):
	root_x = root(x)
	root_y = root(y)

	if root_x != root_y :
		if parent[root_x] > parent[root_y] :
			parent[root_x]=root_y
		else :
			if parent[root_x] == parent[root_y] :
				parent[root_x] -= 1
			parent[root_y] = root_x
    
	return

for _ in range(M) :
	X, Y, Z = map(int, input().split())
	unite(X, Y)
	
print(sum(i < 0 for i in parent) - 1)