C# Solution | Union Find | O(nlogn)
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity: O(nlogn)\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: O(n)\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\npublic class Solution {\n    public int MaxNumEdgesToRemove(int n, int[][] edges) {\n        DSU dsu1 = new DSU(n);\n        DSU dsu2 = new DSU(n);\n        int count = 0;\n        Array.Sort(edges, (a, b) => b[0] - a[0]);\n\n        foreach(var edge in edges){\n            if(edge[0] == 3){\n                if(dsu1.find(edge[1]) == dsu1.find(edge[2]) && dsu2.find(edge[1]) == dsu2.find(edge[2])){\n                    count++;\n                    continue;\n                }\n                \n                dsu1.union(edge[1], edge[2]);\n                dsu2.union(edge[1], edge[2]);\n            }\n            else if(edge[0] == 1){\n                if(dsu1.find(edge[1]) == dsu1.find(edge[2])){\n                    count++;\n                }\n\n                dsu1.union(edge[1], edge[2]);\n            }\n            else{\n                if(dsu2.find(edge[1]) == dsu2.find(edge[2])){\n                    count++;\n                }\n\n                dsu2.union(edge[1], edge[2]);\n            }\n        }\n\n        for(int i=1; i<=n; i++){\n            dsu1.find(i);\n            dsu2.find(i);\n        }\n\n        for(int i=2; i<=n; i++){\n            if(dsu1.parent[i] != dsu1.parent[1] || dsu2.parent[i] != dsu2.parent[1]){\n                return -1;\n            }\n        }\n\n        return count;\n    }\n\n    class DSU {\n        public int[] parent;\n\n        public DSU(int n) {\n            parent = new int[n+1];\n\n            for (int i = 0; i <= n; i++) parent[i] = i;\n        }\n\n        public int find(int x) {\n            if (parent[x] != x) parent[x] = find(parent[x]);\n            return parent[x];\n        }\n\n        public void union(int x, int y) {\n            parent[find(x)] = parent[find(y)];\n        }\n    }\n}\n```
['Union Find', 'Graph', 'C#']