// #pragma GCC optimize ("O3")
// #pragma GCC target   ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
// #pragma GCC optimize ("Ofast,no-stack-protector")
// #pragma GCC optimize ("unroll-loops")
// #pragma GCC optimize ("fast-math")
// #pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>
using namespace std;

typedef long long int      ll;
typedef long double        ld;
typedef unsigned long long ull;
typedef vector<ll>         vl;
typedef vector<vl>         vvl;
typedef pair<ll,ll>        pll;
typedef vector<pll>        vpll;

#define ff          first
#define ss          second
#define pb          push_back
#define mp          make_pair
#define mt          make_tuple
#define eb          emplace_back
#define fr(i,n)     for(ll i = 0; i < n; ++i)
#define frs(i,s,n)  for(ll i = s; i < n; ++i)
#define frb(i,s,e)  for(ll i = s; i <= e; ++i)
#define rfr(i,n)    for(ll i = n-1; i >= 0; i--)
#define frbr(i,e,s) for(ll i = e; i >= s; i--)
#define all(x)      (x).begin(), (x).end()
#define sz(x)       ((ll)(x).size())

template <typename A, typename B>
string to_string(pair<A, B> p);
 
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);
 
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);
 
string to_string(const string& s) 
{
  return '"' + s + '"';
}
 
string to_string(const char* s) 
{
  return to_string((string) s);
}
 
string to_string(bool b) 
{
  return (b ? "true" : "false");
}
 
string to_string(vector<bool> v) 
{
  bool first = true;
  string res = "{";
  for(int i = 0; i < static_cast<int>(v.size()); i++) 
  {
    if(!first) 
       res += ", ";
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}
 
template <size_t N>
string to_string(bitset<N> v) 
{
  string res = "";
  for(size_t i = 0; i < N; i++) 
    res += static_cast<char>('0' + v[i]);
  return res;
}
 
template <typename A>
string to_string(A v) 
{
  bool first = true;
  string res = "{";
  for(const auto &x : v) 
  {
    if(!first) 
       res += ", ";
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}
 
template <typename A, typename B>
string to_string(pair<A, B> p) 
{
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
 
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) 
{
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}
 
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) 
{
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}
 
void debug_out() { cerr << "]\n"; }
 
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) 
{
  cerr << to_string(H);
  if(sizeof...(T)) 
     cerr << ", "; 
  debug_out(T...);
}

clock_t start_time = clock();
double get_current_time() 
{
  return ((double)(clock() - start_time)) / CLOCKS_PER_SEC;
} 

#ifdef LOCAL
#define dbg(...)       {cerr << "[" << #__VA_ARGS__ << "] = [", debug_out(__VA_ARGS__);}
#define dbg_arr(a,n)   {cerr << "[" << #a << "] = [ "; fr(i,n) cerr << a[i] << " "; cerr << "]\n";}
#define dbg_mat(m,r,c) {cerr << "[" << #m << "]:\n"; fr(i,r) {cerr << "[ "; fr(j,c) cerr << m[i][j] << " "; cerr << "]\n";}}
#define dbg_time()     {cerr << "\n" << "Time elapsed: " << get_current_time() << "\n\n\n";}
#else
#define dbg(x...)      {}
#define dbg_arr(a,n)   {}
#define dbg_mat(m,r,c) {}
#define dbg_time()     {}
#endif

const ld PI   = acos(-1);
const ld EPS  = 1e-9;
const ll INF  = 1e18;
const ll SINF = 1e9;
const ll MOD  = 1e9+7; // 998244353;
const ll MAX  = 200100;


void pre()
{
  // factorizer::sieve();
  // prepare_factorials();
}

void solve()
{
  ll n, m; cin >> n >> m;
  set < pll > edg;
  fr(i, m)
  {
    ll x, y; cin >> x >> y;
    x--; y--;
    if(x  > y)
     swap(x, y);
    edg.insert({x, y}); 
  } 
  ll ans = 0;
  vvl graph(n);
  for(auto p: edg)
  {
    graph[p.ff].pb(p.ss);
    graph[p.ss].pb(p.ff);
  }
  vl vis(n, 0);
  auto bfs = [&](ll idx)
  {
    ll cnt = 1;
    queue < ll > q;
    q.push(idx);
    vis[idx] = 1;
    while(!q.empty())
    {
      ll id = q.front();
      q.pop();
      for(auto x: graph[id])
      {
        if(!vis[x])
        {
          vis[x] = 1;
          cnt++;
          q.push(x);
        }
      }
    }
    return cnt;
  };
  fr(i, n)
  {
    if(!vis[i])
    {
      ll k = bfs(i);
      ans = max(ans, k);
    }
  }
  cout << ans << "\n";
}



signed main()
{  
  ios::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);

  // cout << fixed << setprecision(15);

  #ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  pre();

  ll t = 1;
  // cin >> t;
  frb(CASE, 1, t)
  {
    // cout << "Case #" << CASE << ": ";
    // dbg(CASE);
    solve();
  }

  dbg_time();
  
  return 0;
}     
     


Measured memory_bytes: 30924