class DisjointSet:
    def __init__(self, n):
        self.parent = list(range(n))
        self.size = [1] * n

    def find(self, node):
        while self.parent[node] != node:
            self.parent[node] = self.parent[self.parent[node]]
            node = self.parent[node]
        return node

    def union(self, a, b):
        a, b = self.find(a), self.find(b)
        if a == b:
            return False
        if self.size[a] < self.size[b]:
            a, b = b, a
        self.parent[b] = a
        self.size[a] += self.size[b]
        return True


def minimum_spanning_forest(n, edges):
    if n < 0 or any(not (0 <= a < n and 0 <= b < n) for _, a, b in edges):
        raise ValueError('invalid vertex')
    sets = DisjointSet(n)
    chosen, cost, components = [], 0, n
    for weight, a, b in sorted(edges):
        if sets.union(a, b):
            chosen.append((weight, a, b))
            cost += weight
            components -= 1
    return cost, chosen, components


if __name__ == '__main__':
    print(minimum_spanning_forest(4, [(2, 0, 1), (1, 1, 2), (4, 0, 2), (3, 2, 3)]))
