[Python] Union-Find 3 times - O(N)
Idea\n\nWe simply run Union-Find three times:\n\n- first on Type1 \n- then on Type2 and Type3 simultaneously\n\nIncrement ans whenever we find redundant edges. 
**Idea**\n\nWe simply run Union-Find three times:\n\n- first on `Type1` \n- then on `Type2` and `Type3` simultaneously\n\nIncrement `ans` whenever we find redundant edges. Remember to check if the graph is fully connected at the end.\n\n<br />\n\n**Complexity**\n\nTime complexity: `O(N)`\nSpace complexity: `O(N)`\n\n<br />\n\n**Python**\n```Python\nclass UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [1] * n\n        self.size = 1\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n        elif self.ranks[pv] > self.ranks[pu]:\n            self.parents[pu] = pv\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += 1\n        self.size += 1\n        return True\n    \n    \nclass Solution:\n    def maxNumEdgesToRemove(self, n: int, edges: List[List[int]]) -> int:\n        uf1, uf2, ans = UnionFindSet(n), UnionFindSet(n), 0\n\t\t\n        for t, u, v in edges:\n            if t != 3:\n                continue\n            if not uf1.union(u - 1, v - 1) or not uf2.union(u - 1, v - 1):\n                ans += 1\n        \n        for t, u, v in edges:\n            if t == 1 and not uf1.union(u - 1, v - 1):\n                ans += 1\n            elif t == 2 and not uf2.union(u - 1, v - 1):\n                ans += 1\n   \n        return ans if uf1.size == n and uf2.size == n else -1\n```
[]