C++(Using Disjoint Set)
Please Upvote  if you like the Solution!\n\n    class Solution {\n    public:\n    bool static comp(vector &a ,vector &b)//Compare according to type-3\n    {\n 
**Please Upvote  if you like the Solution!**\n\n    class Solution {\n    public:\n    bool static comp(vector<int> &a ,vector<int> &b)//Compare according to type-3\n    {\n        return a[0]>b[0];\n    }\n    int findparent(int node,vector<int> &parent)//find parent function (fro disjoint set)\n    {\n        if(node==parent[node])\n            return node;\n        return parent[node]=findparent(parent[node],parent);\n    }\n    bool unionn(int u,int v,vector<int> &parent,vector<int> &rank)//Union function\n    {\n        u=findparent(u,parent);\n        v=findparent(v,parent);\n        \n        if(u!=v)// when u and v are not equal return true else return false\n        {\n            if(rank[u]<rank[v])\n                parent[u]=v;\n            else if(rank[u]>rank[v])\n                parent[v]=u;\n            else\n            {\n                parent[v]=u;\n                rank[u]++;\n            }\n            return true;\n        }\n        return false;\n    }\n    int maxNumEdgesToRemove(int n, vector<vector<int>>& edges) \n    {\n        sort(edges.begin(),edges.end(),comp);//sort according to type 3, because type 3 solves problem of both alice and bob\n        \n        vector<int> parent_Alice(n+1);\n        vector<int> parent_Bob(n+1);\n        vector<int> rank_Alice(n+1);\n        vector<int> rank_Bob(n+1);\n        \n        //Initialize the parent and rank Array\n        for(int i=0;i<parent_Alice.size();i++)\n        {\n            parent_Alice[i]=i;//intially every node is their own parent and rank of all is 1\n            parent_Bob[i]=i;\n            rank_Alice[i]=1;\n            rank_Bob[i]=1;\n        }\n        int merge_Alice=1;//to count how many nodes we already processed for alice\n        int merge_Bob=1;//to count how many nodes we already processed for bob\n        \n        int remove_edges=0;//for counting how many edges we remove\n        \n        for(auto it:edges)\n        {\n            if(it[0]==3)//for type-3 edges,which is followed by both bob and Alice\n            {\n                bool temp_Alice=unionn(it[1],it[2],parent_Alice,rank_Alice);//unionn when it[0] is of type-3 for Alice\n                bool temp_Bob=unionn(it[1],it[2],parent_Bob,rank_Bob);//unionnn when it[0] is of type-3 for Bob\n                 if(temp_Alice==true)//if it[0] and it[1] are not merged increase merge count\n                    merge_Alice++;\n                \n                if(temp_Bob==true)\n                    merge_Bob++;\n                \n                if(temp_Alice==false && temp_Bob==false)//when they are already merged,then increase count of removed edges\n                    remove_edges++;\n            }\n            else if(it[0]==1)//for type 1, path followed by Alice\n            {\n                 bool temp_Alice=unionn(it[1],it[2],parent_Alice,rank_Alice);//unionn for Alice\n                \n                 if(temp_Alice==true)//if unionn function is true, increase merge_ALice count\n                    merge_Alice++;\n                 else\n                     remove_edges++;//increase remove edges count, if unionn is false\n            }\n            else\n            {\n                bool temp_Bob=unionn(it[1],it[2],parent_Bob,rank_Bob);//for type2,which is followed by bob\n                 \n                if(temp_Bob==true)\n                    merge_Bob++;\n                 else\n                     remove_edges++;\n            }\n        }\n        if(merge_Alice!=n || merge_Bob!=n)//when merge count is not equal to number of nodes return -1\n        {\n            return -1;\n        }\n        return remove_edges;\n      }\n      };
['Union Find', 'C', 'C++']