Somewhat Kruskal's Algo | Union-Find
\nclass Solution {\npublic:\n\n    // The idea is to connect type 3 vertices first, without forming any cycle. Then again do the same for type 1, and type 2. \n
```\nclass Solution {\npublic:\n\n    // The idea is to connect type 3 vertices first, without forming any cycle. Then again do the same for type 1, and type 2. \n\t\n    vector<int> par;\n    \n    int find(int x){\n        if(par[x]==x)\n            return x;\n        return par[x]=find(par[x]);\n    }\n    \n    void merge(int x, int y){\n        int a=find(x);\n        int b=find(y);\n        par[a]=b;\n    }\n    \n    int isValid(int type, vector<vector<int>>& edges){\n        int c=0;\n        int m=edges.size();\n        for(int i=0;i<m;i++){\n            if(edges[i][0]==type && find(edges[i][1])!=find(edges[i][2])){\n                c++;\n                merge(edges[i][1], edges[i][2]);\n            }\n        }\n        return c;\n    }\n    \n    int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) {\n        int m=edges.size();\n        for(int i=0;i<=n;i++){\n            par.push_back(i);\n        }\n        int t3=isValid(3, edges);\n        vector<int> p=par;\n        int t1=isValid(1, edges);\n        par=p;\n        int t2=isValid(2, edges);\n        if(t1+t3!=n-1 || t2+t3!=n-1)\n            return -1;\n        return m-t1-t2-t3;\n    }\n};\n```
['C']