There is an infrastructure of n cities with some number of roads connecting these cities. Each roads[i] = [ai, bi] indicates that there is a bidirectional road between cities ai and bi.

The network rank of two different cities is defined as the total number of&nbsp;directly connected roads to either city. If a road is directly connected to both cities, it is only counted once.

The maximal network rank of the infrastructure is the maximum network rank of all pairs of different cities.

Given the integer n and the array roads, return the maximal network rank of the entire infrastructure.

&nbsp;
Example 1:



Input: n = 4, roads = [[0,1],[0,3],[1,2],[1,3]]
Output: 4
Explanation: The network rank of cities 0 and 1 is 4 as there are 4 roads that are connected to either 0 or 1. The road between 0 and 1 is only counted once.


Example 2:



Input: n = 5, roads = [[0,1],[0,3],[1,2],[1,3],[2,3],[2,4]]
Output: 5
Explanation: There are 5 roads that are connected to cities 1 or 2.


Example 3:

Input: n = 8, roads = [[0,1],[1,2],[2,3],[2,4],[5,6],[5,7]]
Output: 5
Explanation: The network rank of 2 and 5 is 5. Notice that all the cities do not have to be connected.


&nbsp;
Constraints:


	2 &lt;= n &lt;= 100
	0 &lt;= roads.length &lt;= n * (n - 1) / 2
	roads[i].length == 2
	0 &lt;= ai, bi&nbsp;&lt;= n-1
	ai&nbsp;!=&nbsp;bi
	Each&nbsp;pair of cities has at most one road connecting them.


class Solution:
    def maximalNetworkRank(self, n: int, roads) -> int:
        max_rank = 0
        connections = {i: set() for i in range(n)}
        for i, j in roads:
            connections[i].add(j)
            connections[j].add(i)
        for i in range(n - 1):
            for j in range(i + 1, n):
                max_rank = max(max_rank, len(connections[i]) +
                               len(connections[j]) - (j in connections[i]))
        return max_rank
class Solution {
    public int maximalNetworkRank(int n, int[][] roads) {
        
        //number of road connected to city
        int[] numRoadsConnectedCity = new int[100 + 1];
        
        //road exist between two two cities
        boolean[][] raadExist = new boolean[n][n];
        
        for(int[] cities : roads){
            
            //increment the count of numbers of connected city
            numRoadsConnectedCity[cities[0]]++;
            numRoadsConnectedCity[cities[1]]++;
            
            //mark road exist, between two cities
            raadExist[cities[0]][cities[1]] = true;
            raadExist[cities[1]][cities[0]] = true;
        }
        
        
        
        int maxRank = 0;
        for(int city1 = 0; city1 < n - 1; city1++){
            for(int city2 = city1 + 1; city2 < n; city2++){
                
                //count total number of road connected to both city
                int rank = numRoadsConnectedCity[city1] + numRoadsConnectedCity[city2];
                
                //just decrement the rank, if both city connected
                if(raadExist[city1][city2]) rank--;
                
                maxRank = Math.max(maxRank, rank);
            }
        }
            
        
        return maxRank;
    }
}
class Solution {
public:
    int maximalNetworkRank(int n, vector<vector<int>>& roads) {
        vector<vector<int>>graph(n,vector<int>(n,0));
        vector<int>degree(n,0);
        for(int i=0;i<roads.size();i++){
            int u=roads[i][0];
            int v=roads[i][1];
            degree[u]++;
            degree[v]++;
            graph[u][v]=1;
            graph[v][u]=1;
        }
        int ans=0;
        for(int i=0;i<graph.size();i++){
            for(int j=0;j<graph.size();j++){
                if(j!=i){
                    int rank=degree[i]+degree[j]-graph[i][j];
                    ans=max(ans,rank);
                }
            }
        }
        return ans;
    }
};
var maximalNetworkRank = function(n, roads) {
    let res = 0
    let map = new Map()
    roads.forEach(([u,v])=>{
        map.set(u, map.get(u) || new Set())
        let set = map.get(u)
        set.add(v)
        
        map.set(v, map.get(v) || new Set())
        set = map.get(v)
        set.add(u)
    })
    
    for(let i=0;i<n;i++){
        if(!map.has(i)) continue
        let uAdj = map.get(i)
        let uCount = uAdj.size;
        for(let j=i+1;j<n;j++){
            if(!map.has(j)) continue
            let vAdj = map.get(j)
            let vCount = vAdj.size
            if(vAdj.has(i)) vCount--
            res = Math.max(uCount+vCount, res)
        }
    }
    return res
};
Maximal Network Rank