[Golang] UnionFind
Complexity\n- Time complexity:\nO(N+E)\n\n- Space complexity:\nO(N)\n\n# Code\n\nfunc maxNumEdgesToRemove(n int, edges [][]int) int {\n    // O(N)\n    AliceUF 
# Complexity\n- Time complexity:\nO(N+E)\n\n- Space complexity:\nO(N)\n\n# Code\n```\nfunc maxNumEdgesToRemove(n int, edges [][]int) int {\n    // O(N)\n    AliceUF := NewUnionFind(n)\n    BobUF := NewUnionFind(n)\n\n    // O(E)\n    edgesRequired := 0\n    for _, edge := range edges {\n        if edge[0] == 3 {\n            // Check for both and increment edgesRequired if one of them required\n            res1 := AliceUF.PerformUnion(edge)\n            res2 := BobUF.PerformUnion(edge)\n            if res1 || res2 {\n                edgesRequired++\n            }\n        }\n    }\n\n    // O(E)\n    for _, edge := range edges {\n        if edge[0] == 1 && AliceUF.PerformUnion(edge) {\n            edgesRequired++\n        } else if edge[0] == 2 && BobUF.PerformUnion(edge) {\n            edgesRequired++\n        }\n    }\n\n    if AliceUF.isConnected() && BobUF.isConnected() {\n        return len(edges) - edgesRequired\n    }\n\n    return -1\n}\n\ntype UnionFind struct {\n    Parents []int\n    Ranks []int\n    Groups int\n}\n\nfunc NewUnionFind(n int) *UnionFind {\n    parents := make([]int, n+1)\n    for i := 1; i <= n; i++ {\n        parents[i] = i\n    }\n\n    return &UnionFind{\n        Parents : parents,\n        Ranks : make([]int, n+1),\n        Groups : n,\n    }\n}\n\nfunc (uf *UnionFind) PerformUnion(edge []int) bool {\n    p1 := uf.findParent(edge[1])\n    p2 := uf.findParent(edge[2])\n\n    if p1 == p2 {\n        return false\n    }   \n\n    if uf.Ranks[p1] > uf.Ranks[p2] {\n        uf.Parents[p2] = p1\n    } else if uf.Ranks[p2] > uf.Ranks[p1] {\n        uf.Parents[p1] = p2\n    } else {\n        uf.Parents[p2] = p1\n        uf.Ranks[p1]++\n    }\n\n    uf.Groups--\n    return true\n}\n\nfunc (uf *UnionFind) findParent(idx int) int {\n    if idx != uf.Parents[idx] {\n        uf.Parents[idx] = uf.findParent(uf.Parents[idx])\n    }\n    return uf.Parents[idx]\n}\n\nfunc (uf *UnionFind) isConnected() bool {\n    return uf.Groups == 1\n}\n```
['Go']