//g++ -std=c++17 -Wshadow -Wall -fsanitize=address -fsanitize=undefined -D_GLIBCXX_DEBUG -g PROGRAM -o OUTPUT -DLOCAL -lasan -lubsan
#include <bits/stdc++.h>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define alli(a, n, k) (a + k), (a + n + k)
#define FP(i, a, b, k) for (__typeof(a) i = a; i < b; i += k)
#define FS(i, a, b, k) for (__typeof(a) i = a; i > b; i -= k)
#define IT(it, a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); ++it)
#define eps 1e-6
#define pi 3.141592653589793
using namespace std;
using namespace __gnu_pbds;

template <class T>
inline T gcd(T x, T y)
{
    if (!y)
        return x;
    return gcd(y, x % y);
}
typedef vector<int> VII;
typedef vector<ll> VLL;
typedef pair<int, int> PII;
typedef vector<pair<int, int>> VPII;
typedef vector<pair<int, PII>> VPPI;
const int MOD = 1e9 + 7;
const int INF = 1e9;


inline ll modulo(ll a, ll m)
{
    return (a % m + m) % m;
}

inline ll modInverse(ll a, ll m)
{
    assert(__gcd(a, m) == 1);
    ll m0 = m;
    ll y = 0, x = 1;

    if (m == 1)
        return 0;

    while (a > 1)
    {
        ll q = a / m;
        ll t = m;

        m = a % m, a = t;
        t = y;

        y = x - q * y;
        x = t;
    }

    if (x < 0)
        x += m0;

    return x;
}

inline ll modPow(ll x, ll y, ll m)
{ //x^y % m
    if (y == 0)
        return 1LL;
    else if (y == 1)
        return x;
    else
    {
        ll ans = modPow(x, y / 2, m) % m;
        if (y & 1)
        {
            return (((ans * ans) % m) * x) % m;
        }
        else
        {
            return (ans * ans) % m;
        }
    }
}

vector<string> split(char d,string s)
{
    stringstream ss(s);
    string t;
    vector<string> words;
    while(getline(ss,t,d))
    {
        words.pb(t);
    }

    return words;
}
VII dsu(2e5 + 2, -1);
VII sz(2e5 + 2, 1);
int ans = 1;
int root(int x)
{
    if(dsu[x]==-1)
        return x;
    sz[dsu[x]] = sz[x];
    return dsu[x] = x;
}
void join(int a,int b)
{
    int x = root(a);
    int y = root(b);
    if(x==y)
        return;

    dsu[y] = x;
    sz[x] += sz[y];
    sz[y] = sz[x];
    ans = max(ans, sz[x]);
}
class DisjointSet
{
private:
    vector<int> label; //label[x] stores the root of x if x is not root, otherwise it stores -(size of x's set).
public:
    DisjointSet() {}
    DisjointSet(int n)
    {
        label.assign(n + 7, -1); //label should contains at least n+1 elements, as x is 1-indexed.
                                 //At first, each node is a seperate set of size 1.
    }
    int find(int x)
    { //find the root of set which contains x.
        if (label[x] < 0)
            return (x); //x is root iff label[x] is negative.
        label[x] = find(label[x]);
        return (label[x]); //find the root of x by recursion.
    }
    bool join(int a, int b)
    { // join the sets which contains a and b. Return false iff a and b are already in the same set.
        int x = find(a);
        int y = find(b);
        if (x == y)
            return (false); //A set contains both a and b.
        if (label[x] > label[y])
            swap(x, y); //label[x]>label[y] means size(x)<size(y).
        //We speed up the disjoint set by joinning the smaller set to the bigger set
        label[x] += label[y];
        label[y] = x; //Update the label of x and y.
        return (true);
    }
    int getSize(int x)
    { //return the size of set which contains x.
        return (-label[find(x)]);
    }
};
int main(int argc, char *argv[])
{
#ifdef LOCAL
    auto start = chrono::high_resolution_clock::now();
#endif
    
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int n, m;
    cin >> n >> m;
    DisjointSet dsu(n);
    for (int i = 0; i < m;++i)
    {
        int x, y;
        cin >> x >> y;
        dsu.join(x, y);
    }
    for (int i = 1; i <= n;++i)
        ans = max(ans, dsu.getSize(i));
    cout << ans;

#ifdef LOCAL
    auto end = chrono::high_resolution_clock::now();
    double time_taken =
        chrono::duration_cast<chrono::nanoseconds>(end - start).count();

    time_taken *= 1e-9;

    cerr << "\nTime taken by program is : " << fixed
         << time_taken << setprecision(9);
    cerr << " sec" << endl;
#endif
    return 0;
}


Measured memory_bytes: 5564