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 C++ (GCC 9.2.1) (judge verdict: Accepted)

#include<bits/stdc++.h>
using namespace std;
#define fast_io ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define forp(i,a,b) for (int i = (a); i <(b); i++)
#define forn(i,a,b) for (int i = (a); i >(b); i--)
#define mod 1000000007
#define multiple_testcases_t int t;cin>>t;while(t--){solve();}
#define single_testcase_t solve();
typedef long long int ll;
typedef vector<int> vi;
typedef pair<int,int> pii;


int root(int Arr[],int i)
    {
        while(Arr[i] != i)
        {
            Arr[i] = Arr[Arr[i]]; 
            i = Arr[ i ]; 
        }
    return i;
    }

bool find(int Arr[],int A,int B)
    {
        if( root(Arr,A)==root(Arr,B) )
        return true;
        else
        return false;
    }

void weighted_union(int Arr[],int size[],int A,int B)
    {
        int root_A = root(Arr,A);
        int root_B = root(Arr,B);
        if(size[root_A] < size[root_B ])
        {
         Arr[ root_A ] = Arr[root_B];
         size[root_B] += size[root_A];
        }
        else
        {
         Arr[ root_B ] = Arr[root_A];
         size[root_A] += size[root_B];
        }
    }

void initialize(int Arr[],int size[],int N)
    {
        for(int i = 0;i<N;i++)
        {
          Arr[ i ] = i;
          size[ i ] = 1;
        }
    } 

// <----- Actual solve() function to print output -----> //

void solve()
{
   ll n,m,k=0,p,q,ans=0;
   cin>>n>>m;
   int arr[n],size[n];
   initialize(arr,size,n);
   forp(i,0,m)
   {
      cin>>p>>q;
      p--,q--;
      weighted_union(arr,size,p,q);
   }
vector<int> v;
int count[n]={0};
   forp(i,0,n)
   {
       count[root(arr,i)]++;
       if(count[root(arr,i)]>ans)
       ans=count[root(arr,i)];
   }
   cout<<ans;
   //cout<<m*w<<" ";
   //cout<<"\n";      //if t>1 uncomment this
}

// MAIN function --------------------------------------------------------------------------//
int main()
{
    fast_io
//  if taking input from input.txt then uncomment below line
//    freopen("input.txt", "r", stdin);
//  if writing output to output.txt then uncomment below line
//    freopen("output.txt", "w", stdout);

    single_testcase_t   //Uncomment this if only single testcase & single answer to print
  //multiple_testcases_t  //Uncomment this if t>1(t is given in question)(multiple testcases)
return 0;
}