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;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<string, string> pss;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<ll> vl;
typedef vector<vl> vvl;

double EPS=1e-9;
int INF=1000000005;
long long INFF=1000000000000000005ll;
double PI=acos(-1);
int dirx[8]={ -1, 0, 0, 1, -1, -1, 1, 1 };
int diry[8]={ 0, 1, -1, 0, -1, 1, -1, 1 };
const ll MOD = 1000000007;

#define DEBUG fprintf(stderr, "====TESTING====\n")
#define VALUE(x) cerr << "The value of " << #x << " is " << x << endl
#define OUT(x) cout << x << endl
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define READ(x) for(auto &(z):x) cin >> z;
#define FOR(a, b, c) for (int(a)=(b); (a) < (c); ++(a))
#define FORN(a, b, c) for (int(a)=(b); (a) <= (c); ++(a))
#define FORD(a, b, c) for (int(a)=(b); (a) >= (c); --(a))
#define FORSQ(a, b, c) for (int(a)=(b); (a) * (a) <= (c); ++(a))
#define FORC(a, b, c) for (char(a)=(b); (a) <= (c); ++(a))
#define EACH(a, b) for (auto&(a) : (b))
#define REP(i, n) FOR(i, 0, n)
#define REPN(i, n) FORN(i, 1, n)
#define MAX(a, b) a=max(a, b)
#define MIN(a, b) a=min(a, b)
#define SQR(x) ((ll)(x) * (x))
#define RESET(a, b) memset(a, b, sizeof(a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ALL(v) v.begin(), v.end()
#define ALLA(arr, sz) arr, arr + sz
#define SIZE(v) (int)v.size()
#define SORT(v) sort(ALL(v))
#define REVERSE(v) reverse(ALL(v))
#define SORTA(arr, sz) sort(ALLA(arr, sz))
#define REVERSEA(arr, sz) reverse(ALLA(arr, sz))
#define PERMUTE next_permutation
#define TC(t) while (t--)
#define FAST_INP  ios_base::sync_with_stdio(false);cin.tie(NULL)

class DSU {
private:
    vector<ll> d, sz;
public:
    DSU(ll n) {
        d=vector<ll>(n);
        sz=vector<ll>(n, 1);
        REP(i,n) d[i]=i;
    }

    ll p(ll a) {
        if (d[a]==a) return a;
        else return d[a]=p(d[a]);
    }

    ll get_sz(ll a) {
        return sz[p(a)];
    }

    void unite(ll a, ll b) {
        ll pa=p(a);
        ll pb=p(b);
        if (pa==pb) return;
        else {
            sz[pb]+=sz[pa];
            sz[pa]=0;
            d[pa]=pb;
            return;
        }
        return;
    }
};

void solve() {

}

int main()
{
    FAST_INP;
//    #ifndef ONLINE_JUDGE
//    freopen("input.txt","r", stdin);
//    freopen("output.txt","w", stdout);
//    #endif
//
//    int tc; cin >> tc;
//    TC(tc) solve();
	ll n, m, a, b;
	cin >> n >> m;
//	vi vis(n,0),color(n,0);
//	vvi adj(n);
	DSU dsu=DSU(n);
    REP(i,m){
    	cin >> a >> b;
    	--a,--b;
//    	adj[a].pb(b);
//    	adj[b].pb(a);
		dsu.unite(a,b);
	}
//	int k=0;
//	queue<int> q;
//	q.push(0);
//	while(!q.empty()){
//		int u = q.front();
//		q.pop();
//		int c=k;
//		EACH(v, adj[u]){
//			if(!color[v]){
//				dfs(adj,color,v,c);
//				color[v]=c;
//			}
//		}
//	}
//	int ans=0;
//	REP(i,n) ans+=color[i]?1:0;
//	OUT(ans);
	int ans=-INT_MAX;
	REP(i,n) MAX(ans, (int)dsu.get_sz(i));
	OUT(ans);
    return 0;
}