take the common edge first || brute force || easy to understand || must see
Code\ncpp []\nclass Solution {\npublic:\n    int N;\n    bool bobFlag = true;\n    bool aliceFlag = true;\n    set<vector<int>>bobSet;\n    set<vector<int>>alic
# Code\n```cpp []\nclass Solution {\npublic:\n    int N;\n    bool bobFlag = true;\n    bool aliceFlag = true;\n    set<vector<int>>bobSet;\n    set<vector<int>>aliceSet;\n    int maxNumEdgesToRemove(int n, vector<vector<int>>& arr) {\n          N = n;\n          sort(arr.begin(),arr.end());\n\n          vector<vector<int>>bob;\n          vector<vector<int>>alice;\n          \n          for(int i = arr.size()-1 ; i >=0 ; i--){\n              if((arr[i][0] == 1) or (arr[i][0] == 3)){\n                   alice.push_back(arr[i]);\n              }\n              if((arr[i][0] == 2) or (arr[i][0] == 3)){\n                   bob.push_back(arr[i]);\n              }\n          }\n          funAlice(alice); if(aliceFlag == false) return -1;\n          funBob(bob); if(bobFlag == false) return -1;\n\n        //   cout<<"alice choise of the edges"<<endl;\n        //   for(auto v : aliceSet){\n        //       cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<endl;\n        //   }\n        //   cout<<endl;\n        //   cout<<endl;\n        //   for(auto v : bobSet){\n        //       cout<<v[0]<<" "<<v[1]<<" "<<v[2]<<endl;\n        //   }\n        //   cout<<endl;\n          return arr.size() - (aliceSet.size() + bobSet.size());\n          \n    }\n    void funBob(vector<vector<int>>&Bob){\n         vector<int>par(N+1,0);\n         vector<int>rank(N+1,0);\n         for(int i = 0 ; i < par.size() ; i++) par[i] = i;\n\n         for(int i = 0 ; i < Bob.size() ; i++){\n             \n             int u = Bob[i][1];\n             int v = Bob[i][2];\n             if(union_rank(par,rank,u,v) == true){\n                   int a = u;\n                   int b = v;\n                   if(a > b) {\n                       int c=a;\n                       a=b;\n                       b=c;\n                   }\n                   if((Bob[i][0] == 2) or ((Bob[i][0] == 3) and (aliceSet.find({Bob[i][0] , a , b}) == aliceSet.end())))\n                   bobSet.insert({Bob[i][0] , a , b});\n             }\n         }\n         unordered_set<int>st;\n         for(int i = 1 ; i <= N ; i++) {\n              par[i] = find_parent(i,par);\n              st.insert(par[i]);\n         }\n         if(st.size() > 1) bobFlag = false; \n    }\n    void funAlice(vector<vector<int>>&alice){\n         vector<int>par(N+1,0);\n         vector<int>rank(N+1,0);\n         for(int i = 0 ; i < par.size() ; i++) par[i] = i;\n\n         for(int i = 0 ; i < alice.size() ; i++){\n             \n             int u = alice[i][1];\n             int v = alice[i][2];\n             if(union_rank(par,rank,u,v) == true){\n                   int a = u;\n                   int b = v;\n                   if(a > b) {\n                       int c=a;\n                       a=b;\n                       b=c;\n                   }\n                   aliceSet.insert({alice[i][0] , a , b});\n             }\n         }\n         unordered_set<int>st;\n         for(int i = 1 ; i <= N ; i++) {\n              par[i] = find_parent(i,par);\n              st.insert(par[i]);\n         }\n         if(st.size() > 1) aliceFlag = false; \n         \n    }\n    int find_parent(int u , vector<int>&parent){\n        if(parent[u] == u) return u;\n        return parent[u] = find_parent(parent[u],parent);\n    }\n    bool union_rank(vector<int>&par,vector<int>&rank,int u,int v){\n        int paru = find_parent(u,par);\n        int parv = find_parent(v,par);\n\n        if(paru == parv) return false;\n\n        if(rank[paru] == rank[parv]){\n              par[parv] = paru;\n              rank[paru]++;\n        }\n        else if(rank[paru] < rank[parv]){\n              par[paru] = parv;\n        }\n        else if(rank[parv] < rank[paru]){\n              par[parv] = paru;\n        }\n        return true;\n    }\n    void print(vector<vector<int>>&arr){\n         for(int i = 0 ; i < arr.size() ; i++){\n            for(int j = 0 ; j < arr[i].size() ; j++){\n                cout<<arr[i][j]<<" ";\n            }\n            cout<<"    ";\n         }\n         return;\n    }\n};\n```
['Union Find', 'Graph', 'C++']