/**
  *  Author: dhruv_gheewala
  *  Problem: D - Friends
  *  Date:   10.09.2020
  *  Time:   14:54:52
**/

#if __has_include("debug.h")
    #include "debug.h"
#else
    #include<bits/stdc++.h>
    using namespace std;
    
    #define fundri 108
    #define debug(...) 1729
#endif

#define int int64_t
typedef pair<int, int> pii;
typedef vector<int> vi;

const bool testcases = false;
#define ff first
#define ss second
#define endl '\n'
#define all(s) s.begin(), s.end()

// if vector isn't soted then it will remove consecutive same elements
#define make_unique(vec) vec.erase(unique(all(vec)), vec.end())
#define test int TC = 1;if(testcases)cin >> TC;for(int tc = 1 ; tc <= TC ; tc++)solve(), fundri
#define sort_by(cont,expr) sort(all(cont),[&](const auto &lhs,const auto &rhs){return expr;})
// clears stdin
#define flush(ch) cin.ignore(std::numeric_limits<std::streamsize>::max(), ch) // default, EOF

int seed; mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
inline int rnd(int l = 0, int r = INT_MAX) {return uniform_int_distribution<int>(l, r)(rng);}

inline bool in_range(int a, int l, int r) {return (a >= l && a <= r);}
template<typename H, typename ...T>void inp(H &head) {cin >> head;}
template<typename H, typename ...T>void inp(H &head, T &...tail) {cin >> head;inp(tail...);}
template<typename T>bool isPrime(T n) {for(T i = 2; i * i <= n; i++)if(n % i == 0)return false; return n >= 2;}
template<typename T>inline istream &operator >>(istream &in, vector<T> &a) {for(T &x : a)in >> x; return in;}
template<typename T, typename U>inline istream &operator >>(istream &in, pair<T, U> &a) {in >> a.ff >> a.ss; return in;}

void solve();
void fast_io();

int32_t main(int32_t argc, char **argv)
{
    fast_io();
    test;
    return 0;
}

class dsu {

private:
    int components, nodes;
    vi parent;
    // multiset<int> sizes;
    // set<int> roots;
    
public:
    
    dsu(): components(0), nodes(0) {};
    dsu(int size)
    {
        int mini = 1;
        init(max(mini, size));
    }
    
    inline void init(int size)
    {
        clear();
        parent.assign(size + 1, -1);
        nodes = components = size;
        
        // for(int i = 1 ; i <= size ; i++) {
        //     sizes.insert(1);
        //     roots.insert(i);
        // }
    }
    
    inline int size() {return nodes;}
    inline int disjoints() {return components;}
    inline int size(int set) {return -parent[find(set)];}
    inline int find(int x) {return parent[x] < 0 ? x : parent[x] = find(parent[x]);}
    inline bool isSameSet(int x, int y) {return find(x) == find(y);}
    
    inline vi givePar() {return parent;}
    // inline vi giveRoot() {return roots;}
    // inline multiset<int> giveSize() {return sizes;}
    
    // if choice is true, then x will be
    // parent of y and it's child
    bool merge(int x, int y, bool choice = 0)
    {
        if(isSameSet(x, y)) return false;
        
        x = find(x);
        y = find(y);
        
        if(!choice && size(x) < size(y)) swap(x, y);
        
        // sizes.erase(sizes.find(size(x)));
        // sizes.erase(sizes.find(size(y)));
        // roots.erase(y);
        
        parent[x] += parent[y];  // changing the size of x. (i.e. root node)
        parent[y] = x;
        // sizes.insert(size(x));
        
        components--;
        return true;
    }
    
    inline void clear()
    {
        parent.clear();
        // sizes.clear();
        // roots.clear();
    }

    inline int operator [](int x)
    {
        assert(x < nodes);
        return parent[x];
    }
};

string to_string(dsu &a)
{
#ifdef DEBUG
    string res = "Parent --> " + to_string(a.givePar()) + '\n';
    // res += "       Roots --> " + to_string(a.giveRoot());
    return res;
#endif
    return "";
}

void solve()
{
    int n, m;
    cin >> n >> m;

    int u, v;
    dsu disj(n);
    for(int i = 0 ; i < m ; i++) {
        cin >> u >> v;
        disj.merge(u, v);
    }

    int ans = 0;
    for(int i = 1 ; i <= n ; i++)
        ans = max(ans, disj.size(i));
    cout << ans << endl;
}

void fast_io()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

#ifdef DHRUV_GHEEWALA
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    freopen("debug.txt", "w", stderr);
#endif
}

Measured memory_bytes: 4832