Problem:
Score : 400 points

Problem Statement

There are N persons called Person 1 through Person N.

You are given M facts that "Person A_i and Person B_i are friends." The same fact may be given multiple times.

If X and Y are friends, and Y and Z are friends, then X and Z are also friends. There is no friendship that cannot be derived from the M given facts.

Takahashi the evil wants to divide the N persons into some number of groups so that every person has no friend in his/her group.

At least how many groups does he need to make?

Constraints

2 \leq N \leq 2\times 10^5

0 \leq M \leq 2\times 10^5

1\leq A_i,B_i\leq N

A_i \neq B_i

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
\vdots
A_M B_M

Output

Print the answer.

Sample Input 1

5 3
1 2
3 4
5 1

Sample Output 1

3

Dividing them into three groups such as \{1,3\}, \{2,4\}, and \{5\} achieves the goal.

Sample Input 2

4 10
1 2
2 1
1 2
2 1
1 2
1 3
1 4
2 3
2 4
3 4

Sample Output 2

4

Sample Input 3

10 4
3 1
4 1
5 9
2 6

Sample Output 3

3

Solution in Java (OpenJDK 11.0.6) (judge verdict: Wrong Answer)

import java.io.*; 
import java.util.*; 
  
class DisjointUnionSets { 
    int[] rank, parent; 
    int n; 
  
    // Constructor 
    public DisjointUnionSets(int n) 
    { 
        rank = new int[n]; 
        parent = new int[n]; 
        this.n = n; 
        makeSet(); 
    } 
  
    // Creates n sets with single item in each 
    void makeSet() 
    { 
        for (int i = 0; i < n; i++) { 
            // Initially, all elements are in 
            // their own set. 
            parent[i] = i; 
        } 
    } 
  
    // Returns representative of x's set 
    int find(int x) 
    { 
        // Finds the representative of the set 
        // that x is an element of 
        if (parent[x] != x) { 
            // if x is not the parent of itself 
            // Then x is not the representative of 
            // his set, 
            parent[x] = find(parent[x]); 
  
            // so we recursively call Find on its parent 
            // and move i's node directly under the 
            // representative of this set 
        } 
  
        return parent[x]; 
    } 
  
    // Unites the set that includes x and the set 
    // that includes x 
    void union(int x, int y) 
    { 
        // Find representatives of two sets 
        int xRoot = find(x), yRoot = find(y); 
  
        // Elements are in the same set, no need 
        // to unite anything. 
        if (xRoot == yRoot) 
            return; 
  
        // If x's rank is less than y's rank 
        if (rank[xRoot] < rank[yRoot]) 
  {
            // Then move x under y  so that depth 
            // of tree remains less 
            parent[xRoot] = yRoot; 
            rank[yRoot]++;
  }
        // Else if y's rank is less than x's rank 
        else if (rank[yRoot] < rank[xRoot]) 
  {
            // Then move y under x so that depth of 
            // tree remains less 
            parent[yRoot] = xRoot; 
            rank[xRoot]++;
  }
        else // if ranks are the same 
        { 
            // Then move y under x (doesn't matter 
            // which one goes where) 
            parent[yRoot] = xRoot; 
  
            // And increment the result tree's 
            // rank by 1 
            rank[xRoot] = rank[xRoot] + 1; 
        } 
    } 
} 
  
// Driver code 
public class Main { 
    public static void main(String[] args) 
    { 
        // Let there be 5 persons with ids as 
        // 0, 1, 2, 3 and 4 
        Scanner in = new Scanner(System.in);
        int n = in.nextInt(); 
        DisjointUnionSets dus =  
                new DisjointUnionSets(n); 
        
        int m = in.nextInt();

        while(m-- > 0){
            int a = in.nextInt();
            int b = in.nextInt();
            dus.union( a - 1, b - 1);
        }
        int max = 0;
        for(int i = 0 ; i < dus.rank.length ; i++){
            max = Math.max(max,dus.rank[i]);
        }
        System.out.println(max + 1);
    } 
}