Java || Easy Approach with Explanation || Union Find
\nclass Solution {\n    public int maxNumEdgesToRemove(int n, int[][] edges) \n    {\n        Arrays.sort(edges, (a, b)->{\n            return b[0]-a[0];\n     
```\nclass Solution {\n    public int maxNumEdgesToRemove(int n, int[][] edges) \n    {\n        Arrays.sort(edges, (a, b)->{\n            return b[0]-a[0];\n        });//giving the priority to third type of edge or the edge which Bob and Alice both can access\n        \n        //1-based indexing of nodes \n        int []parentAlice= new int[n+1];//Graph 1 for Alice connectedness\n        int []parentBob= new int[n+1];//Graph 2 for Bob connectedness\n        \n        for(int i= 0; i< n+1; i++){//every node is pointing to itself, at first no connection is considered all sets are independent(no dependency) \n            parentAlice[i]= i;\n            parentBob[i]= i;\n        }\n        \n        //number of merged unique node for Alice and Bob that are required to maintain the connectedness of Alice and Bob graph nodes//intialised with one because merging happens in pair \n        int mergeAlice= 1;\n        int mergeBob= 1;\n        \n        //number of cyclic or the non dependent node, that are not required for the connectedness of Alice and Bob nodes  \n        int removeEdge= 0;\n        \n        for(int []edge: edges)\n        {\n            int cat= edge[0];//category of edge 1)edge Alice can only access 2)edge Bob can only access 3)edge both Alice and Bob can access\n            int u= edge[1];\n            int v= edge[2];\n            \n            if(cat == 3){//edge both Alice and Bob an access\n                \n                //creating dependency of nodes in graph 1 and 2 \n                boolean tempAlice= union(u, v, parentAlice);\n                boolean tempBob= union(u, v, parentBob);\n                \n                if(tempAlice == true)\n                    mergeAlice+= 1;\n                \n                if(tempBob == true)\n                    mergeBob+= 1;\n                \n                if(tempAlice == false && tempBob == false)//retundant or the cyclic non-dependent edge//both Alice and Bob don\'t rquire it connection is already there between these pair of nodes\n                    removeEdge+= 1;\n            }\n            else if(cat == 2){//edge Bob can only access \n                \n                //creating dependency of nodes in graph 2\n                boolean tempBob= union(u, v, parentBob);\n                \n                if(tempBob == true)\n                    mergeBob+= 1;\n                else//no merging of set is done, that means that this edge is not required because it will form cycle or the dependency \n                    removeEdge+= 1;\n            }\n            else{//edge Alice can only access \n                \n                //creating dependency of nodes in graph 1\n                boolean tempAlice= union(u, v, parentAlice);\n                \n                if(tempAlice == true)\n                    mergeAlice+= 1; \n                else//no merging of set is done, that means that this edge is not required because it will form cycle or the dependency \n                    removeEdge+= 1;\n            }\n        }\n        if(mergeAlice != n || mergeBob != n)//all node are not connected, connectedness is not maintained \n            return -1;\n        return removeEdge;//number of edge removed by maintaining the connectedness \n    }\n    \n    public int find(int x, int[] parent)\n    {\n        if(parent[x] == x)//when we found the absolute root or the leader of the set \n            return x;\n        \n        int temp= find(parent[x], parent);\n        \n        parent[x]= temp;//Path Compression//child pointing to the absolute root or the leader of the set, while backtracking\n        \n        return temp;//returning the absolute root \n    }\n    \n    public boolean union(int x, int y, int[] parent)\n    {\n        int lx= find(x, parent);//leader of set x or the absolute root\n        int ly= find(y, parent);//leader of set y or the absolute root\n        \n        if(lx != ly){//belong to different set merging \n            \n            //Rank Compression is not done, but you can do it \n            parent[lx]= ly;\n            \n            return true;//union done, dependency created\n        }\n        else\n            return false;//no union done cycle is due to this edge \n    }//Please do Upvote, it helps a lot \n}\n```
['Union Find', 'Graph', 'Java']