// Original C++ solution (slower):


#include<bits/stdc++.h>

using namespace std;

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;

#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

#define ll long long

#define si(n) scanf("%d",&n);

#define PI acos(-1.0)

#define sl(n) scanf("%lld",&n);

#define sf(n) scanf("%lf",&n);

#define ss(n) scanf("%s",n);

#define for0(i,n) for(ll i=0;i<n;i++)

#define for1(i,n) for(ll i=1;i<=n;i++)

#define forc(i,j,n) for(ll i=j;i<n;i++)

#define pb push_back

#define sor(n) sort(n.begin(),n.end())

#define sorcmp(n) sort(n.begin(),n.end(),cmp)

#define rev(n) reverse(n.begin(),n.end())

#define pi(x)  printf("%d",x);

#define pl(x)  printf("%lld",x);

#define pf(x)  printf("%.10lf",x);

#define ps(x)  printf("%s",x);

#define en() printf("\n");

#define random_shuffle(r...)random_shuffle(r,[](int _){return rand()%_;})

#define SQR(a) (a)*(a)

#define sp(x) fixed<<setprecision(x)

#define mod 1000000007

#define endl '\n'

#define pii pair<int,int>

#define pll pair<ll,ll>

#define bug cout<<"Here"<<endl

void fastio(){ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);}

template <typename T> T POW(T B,T P){ if(P==0) return 1; if(P&1) return B*POW(B,P-1);  else return SQR(POW(B,P/2));}

ll powmod(ll a, ll b){ll ans = 1;while(b){if(b&1) ans = ans*a%mod;a = a*a%mod;b >>= 1;}return ans;}



#define mxn 200005

vector<int>g[mxn];

int vis[mxn];



int bfs(int x)

{

    vis[x]++;

    queue<int>q;

    q.push(x);

    int cnt=1;

    while(!q.empty())

    {

        int v=q.front();

        q.pop();



        for(auto u:g[v])

        {

            if(vis[u]) continue;

            vis[u]++;

            cnt++;

            q.push(u);

        }

    }



    return cnt;

}





int main()

{





    int n,m;

    cin>>n>>m;



    while(m--)

    {

        int a,b;

        cin>>a>>b;

        g[a].pb(b);

        g[b].pb(a);

    }

    int mx=-1;

    for(int i=1;i<=n;i++)

    {

        if(vis[i]) continue;

        mx=max(mx,bfs(i));

    }



    cout<<mx<<endl;











	return 0;

}




// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

 

using namespace std;



// traduções



// even -> par

// odd -> impar

// west -> oeste



typedef long long ll;

typedef pair<int, int> ii;

typedef vector<ii> vii;

typedef vector<int> vi;



#define INF 1000000000

#define MOD 1000000007

#define EPS 1e-12

const double PI = acos(-1.0);



#define REP(i, a, b) for(int i = (a); i < (b); ++i)

#define ALL(x) x.begin(), x.end()

#define UNIQUE(c) (c).resize(unique(ALL(c)) - (c).begin())

#define FILL(a,v) memset(a, v, sizeof a)



// bitmask operations

#define SETBIT(S, j) S |= (1 << j)

#define CLEARBIT(S, j) S &= ~(1 << j)

#define ISSET(S, j) S & (1 << j)

#define FLIPBIT(S, j) S ^= (1 << j)

#define LSBIT(S) (S & (-S))



// debug

#define DEBUGSTR(S) cout << "(" << S << ")\n";



int tranform(int i, int j, int M) {

    return j + M*i;

}



class UFDS {

private:

    vi size, ps;

    int numSets;



public:

    UFDS(int N) : size(N + 1, 1), ps(N + 1), numSets(N) {

        iota(ps.begin(), ps.end(), 0);

    }



    int find_set(int x) {

        return x == ps[x] ? x : (ps[x] = find_set(ps[x]));

    }



    bool same_set(int x, int y) {

        return find_set(x) == find_set(y);

    }



    int getMax() {

        int maior = -1;

        int sz = size.size();

        for(int i = 0; i < sz; ++i)

            maior = max(maior, sizeOfSet(i));

        

        return maior;

    }



    int sizeOfSet(int i) { return size[find_set(i)]; }



    int numDisjointSets() const { return numSets; }



    void union_set(int x, int y) {

        int p = find_set(x), q = find_set(y);



        if(p == q)

            return;

        

        numSets--;



        if (size[p] < size[q])

            swap(p, q);



        ps[q] = p;



        size[p] += size[q];

    }

};



int main() {

    //ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

    int N, M;

    scanf(" %d %d", &N, &M);



    UFDS UF(N);



    REP(i, 0, M) {

        int a, b;

        scanf(" %d %d", &a, &b);



        UF.union_set(a, b);

    }



    printf("%d\n", UF.getMax());



    return 0;

}


// Fastest known solution for this problem: