//By Vasu Agrawal
#include<iostream>
#include<bits/stdc++.h>
typedef long long int ll;
#define pb push_back
#define pob pop_back
#define mk make_pair
#define fr first
#define sc second
#define pu push
#define ins insert
#define mod 1000000007
#define mem(a,val) memset(a,val,sizeof(a))
#define V(a) vector<a> 
#define pp pair<ll,ll>
#define lb(a,n) lower_bound(a.begin(),a.end(),n)-a.begin()
#define ub(a,n) upper_bound(a.begin(),a.end(),n)-a.begin()
#define F(i,n) for(ll i=0;i<n;i++)
#define in(a,n) F(i,n) cin>>a[i]
#define in1(a,n) f(i,n) cin>>a[i]
#define out1(a,n); f(i,n) cout<<a[i]<<" ";cout<<endl;
#define out(a,n); F(i,n) cout<<a[i]<<" ";cout<<endl;
#define f(i,n) for(ll i=1;i<=n;i++)
#define vasu2907 ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
using namespace std;
bool isprime(ll n) //Time Complexity--->sqrt(n)
{   if (n <= 1)  return false; if (n <= 3)  return true; 
  	if (n%2 == 0 || n%3 == 0) return false; 
    for (int i=5; i*i<=n; i=i+6) if (n%i == 0 || n%(i+2) == 0) return false; 
    return true; 
} 
vector<ll> prime;
void sieve(ll n) 
{	bool bakh[n+1];memset(bakh, true, sizeof(bakh)); 
    for (ll p=2; p*p<=n; p++) 
    {	if (bakh[p] == true) 
        {	for (ll i=p*p; i<=n; i += p)    bakh[i] = false; } } 
  	for (ll p=2; p<=n; p++)    if (bakh[p])
	  	prime.pb(p); 
}//Taken from https://www.geeksforgeeks.org/eulers-totient-function-for-all-numbers-smaller-than-or-equal-to-n/
ll eulertotient(ll z)   //Time--->n/logn
{	ll fac=z;
	for(ll i=0;prime[i]*prime[i]<=z;i++)
	{	if(z%prime[i]==0)	
		{	fac-=(fac/prime[i]);	while(z%prime[i]==0)	z/=prime[i];	}	
	}	if(z>1)	fac-=(fac/z);
	return fac;
} 
//Taken from https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/
ll power(ll x,ll y,ll p) 
{	ll res = 1; x = x % p;	while (y > 0)  {	if (y & 1)	res = (res*x) % p; 	y = y>>1;	x = (x*x) % p; }return res; } 
//Taken from https://www.geeksforgeeks.org/euclidean-algorithms-basic-and-extended/
ll gcd(ll a,ll b) 
{	if (a == 0)    return b; 	return gcd(b % a, a); }
ll lcm(ll a,ll b)
{	ll g=gcd(a,b); ll ans=(a*b)/g; return ans;	}
//Taken from https://www.geeksforgeeks.org/multiplicative-inverse-under-modulo-m/
ll modInverse(ll a, ll m) 
{	ll hvf=gcd(a,m);	if(hvf==1)	return power(a,m-2,m);	return -1;} 
void multiply(ll F[2][2], ll M[2][2]) 
{ ll x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];  ll y =  F[0][0]*M[0][1] + F[0][1]*M[1][1]; 
  ll z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];  ll w =  F[1][0]*M[0][1] + F[1][1]*M[1][1]; 
  F[0][0] = x;   F[0][1] = y;   F[1][0] = z;   F[1][1] = w; 
}
void powermat(ll F[2][2], ll n) 
{	if( n == 0 || n == 1) 
    return; ll M[2][2] = {{1,1},{1,0}};   powermat(F, n/2);   multiply(F, F);   if (n%2 != 0)      multiply(F, M); 
}
ll fib(ll n) 
{ ll F[2][2] = {{1,1},{1,0}}; 
  if (n == 0) return 0; powermat(F, n-1);   return F[0][0]; 
}
V(ll) merge(V(ll) v1,V(ll) v2)
{	V(ll) temp;
	ll i=0,j=0;
	while(i<v1.size() && j<v2.size())
	{	if(v1[i]<v2[j])
			temp.pb(v1[i]),i++;
		else
			temp.pb(v2[j]),j++;
	}
	while(i<v1.size())	
		temp.pb(v1[i]),i++;
	while(j<v2.size())	
		temp.pb(v2[j]),j++;
	return temp;
}
//id=(id&(id+1))-1
//ll fetch(ll id)
//{		
//}
//id=(id|(id+1))
//void update(ll id)
//{	
//}

//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
// Code Starts Here
V(bool) mark;
ll c;
V(ll) adj[200005];
void dfs(ll u)
{	mark[u]=1;
	c++;
	for(auto v:adj[u])
	{	if(!mark[v])
			dfs(v);
	}
}
int main()
{	vasu2907;
	ll n,m,a,b;
	cin>>n>>m;
	map<pp,int> mp;
	while(m--)
	{	cin>>a>>b;
		if(a>b)	swap(a,b);
		if(mp[{a,b}]==0)
			adj[a].pb(b),adj[b].pb(a),mp[{a,b}]=1;
	}
	mark.resize(n+1,false);
	ll ans=0;
	f(i,n)
	{	if(!mark[i])
		{	c=0;
			dfs(i);
			ans=max(ans,c);
		}
	}
	cout<<ans<<endl;
}	

Measured memory_bytes: 33288