def countComponents2(n: int, edges: list[list[int]]) -> int:
    """
    quick union based implementation

    Args:
        n (int): number of nodes
        edges (list[list[int]]): list of edges

    Returns:
        int: number of connected components
    """
    connections = [n for n in range(n)]

    def get_parent(node):

        while node != connections[node]:
            node = connections[node]
        
        return node

    for edge in edges:
        u, v = get_parent(edge[0]), get_parent(edge[1])

        connections[u] = connections[v]
        
    components = set([get_parent(n) for n in range(n)])

    return len(components)