// Original C++ solution (slower):
#include <bits/stdc++.h>

 

#define pb push_back

#define ff first

#define ss second

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

#define ll long long

#define ii pair<int,int>

#define vi vector<int>

#define vll vector<ll>

#define vii vector<ii>

#define debug cout << "Ok" << endl;



using namespace std;



void solve(){



	return;

}





vector<int>ps(200100);

vector<int>qtd(200100,1);



int find_set(int n){

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

}

int ma=1;



bool insert(int x, int y){

	int xr = find_set(x);

	int yr = find_set(y);

	int l;



	if(xr == yr) return false;



	if(qtd[xr] < qtd[yr]){

		l = xr;

		xr = yr;

		yr = l;

	}



	ps[yr]=xr;

	qtd[xr]+=qtd[yr];

	ma = max(ma,qtd[xr]);

	return true;

}



int32_t main(){

	long long int n,m,a,b;



	cin >> n >> m;

	for(int i=0;i<=n+3;i++){

		ps[i]=i;

	}

	while(m--){

		cin >> a >> b;

		insert(a,b);

	}





	cout << ma << endl;

	return 0;

}

// Optimized solution to the same problem (faster):
#pragma region

#include <algorithm>

#include <cmath>

#include <cstring>

#include <iomanip>

#include <iostream>

#include <map>

#include <queue>

#include <set>

#include <stack>

#include <string>

#include <vector>

using namespace std;

typedef long long ll;

#define rep(i, a, n) for (int i = a; i <= n; ++i)

#define per(i, a, n) for (int i = n; i >= a; --i)

namespace fastIO {

#define BUF_SIZE 100000

#define OUT_SIZE 100000

//fread->R

bool IOerror = 0;

//inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}

inline char nc() {

    static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;

    if (p1 == pend) {

        p1 = buf;

        pend = buf + fread(buf, 1, BUF_SIZE, stdin);

        if (pend == p1) {

            IOerror = 1;

            return -1;

        }

    }

    return *p1++;

}

inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }

template <class T>

inline bool R(T &x) {

    bool sign = 0;

    char ch = nc();

    x = 0;

    for (; blank(ch); ch = nc())

        ;

    if (IOerror) return false;

    if (ch == '-') sign = 1, ch = nc();

    for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';

    if (sign) x = -x;

    return true;

}

inline bool R(double &x) {

    bool sign = 0;

    char ch = nc();

    x = 0;

    for (; blank(ch); ch = nc())

        ;

    if (IOerror) return false;

    if (ch == '-') sign = 1, ch = nc();

    for (; ch >= '0' && ch <= '9'; ch = nc()) x = x * 10 + ch - '0';

    if (ch == '.') {

        double tmp = 1;

        ch = nc();

        for (; ch >= '0' && ch <= '9'; ch = nc())

            tmp /= 10.0, x += tmp * (ch - '0');

    }

    if (sign)

        x = -x;

    return true;

}

inline bool R(char *s) {

    char ch = nc();

    for (; blank(ch); ch = nc())

        ;

    if (IOerror)

        return false;

    for (; !blank(ch) && !IOerror; ch = nc())

        *s++ = ch;

    *s = 0;

    return true;

}

inline bool R(char &c) {

    c = nc();

    if (IOerror) {

        c = -1;

        return false;

    }

    return true;

}

template <class T, class... U>

bool R(T &h, U &... t) { return R(h) && R(t...); }

#undef OUT_SIZE

#undef BUF_SIZE

};  // namespace fastIO

using namespace fastIO;

template <class T>

void _W(const T &x) { cout << x; }

void _W(const int &x) { printf("%d", x); }

void _W(const int64_t &x) { printf("%lld", x); }

void _W(const double &x) { printf("%.16f", x); }

void _W(const char &x) { putchar(x); }

void _W(const char *x) { printf("%s", x); }

template <class T, class U>

void _W(const pair<T, U> &x) { _W(x.F), putchar(' '), _W(x.S); }

template <class T>

void _W(const vector<T> &x) {

    for (auto i = x.begin(); i != x.end(); _W(*i++))

        if (i != x.cbegin()) putchar(' ');

}

void W() {}

template <class T, class... U>

void W(const T &head, const U &... tail) { _W(head), putchar(sizeof...(tail) ? ' ' : '\n'), W(tail...); }

#pragma endregion

const int maxn = 2e5 + 5;

int fa[maxn];

int findroot(int x) { return x == fa[x] ? x : fa[x] = findroot(fa[x]); }

void link(int x, int y) { fa[findroot(x)] = findroot(y); }

int cnt[maxn];

int main() {

    int n, m;

    R(n, m);

    rep(i, 1, n) fa[i] = i;

    while (m--) {

        int x, y;

        R(x, y);

        link(x, y);

    }

    int ans = 0;

    rep(i, 1, n) cnt[findroot(i)]++, ans = max(ans, cnt[findroot(i)]);

    W(ans);

}

// Fastest known solution for this problem: