Problem:
Score : 400 points

Problem Statement

There are N persons called Person 1 through Person N.

You are given M facts that "Person A_i and Person B_i are friends." The same fact may be given multiple times.

If X and Y are friends, and Y and Z are friends, then X and Z are also friends. There is no friendship that cannot be derived from the M given facts.

Takahashi the evil wants to divide the N persons into some number of groups so that every person has no friend in his/her group.

At least how many groups does he need to make?

Constraints

2 \leq N \leq 2\times 10^5

0 \leq M \leq 2\times 10^5

1\leq A_i,B_i\leq N

A_i \neq B_i

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
\vdots
A_M B_M

Output

Print the answer.

Sample Input 1

5 3
1 2
3 4
5 1

Sample Output 1

3

Dividing them into three groups such as \{1,3\}, \{2,4\}, and \{5\} achieves the goal.

Sample Input 2

4 10
1 2
2 1
1 2
2 1
1 2
1 3
1 4
2 3
2 4
3 4

Sample Output 2

4

Sample Input 3

10 4
3 1
4 1
5 9
2 6

Sample Output 3

3

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>

using namespace std;
#define int long long
#define sim template <class c
#define ris return *this
#define dor > debug &operator<<
#define eni(x)                                                                    \
    sim > typename enable_if<sizeof dud<c>(0) x 1, debug &>::type operator<<(c i) \
    {
sim>
struct rge {
    c b, e;
};

sim> rge<c> range(c i, c j) { return rge<c>{i, j}; }

sim> auto dud(c *x) -> decltype(cerr << *x, 0);

sim> char dud(...);

struct debug {
#ifndef LOCAL

    ~debug() {
        cerr << endl;
    }

    eni(!=) cerr << boolalpha << i;
        ris;
    }

    eni(==) ris << range(begin(i), end(i));
    }

    sim, class b dor(pair<b, c> d) {
        ris << "(" << d.first << ", " << d.second << ")";
    }

    sim dor(rge<c> d) {
        *this << "[";
        for (auto it = d.b; it != d.e; ++it)
            *this << ", " + 2 * (it == d.b) << *it;
        ris << "]";
    }

#else
    sim dor(const c &)
    {
        ris;
    }
#endif
};

#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define int long long

void solve();

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
//    test
    solve();
    return 0;
}

const int mxn = 2e5 + 5;
int n, m;
vector<int> adj[mxn];
bool vis[mxn];
int x;

void dfs(int u) {
    if (!vis[u]) {
        vis[u] = true;
        x++;
        for (auto v: adj[u]) {
            if (!vis[v])
                dfs(v);
        }
    }
}

void solve() {
    int n, m;
    cin >> n >> m;
    set<pair<int, int>> s;
    for (int i = 0; i < m; ++i) {
        int a, b;
        cin >> a >> b;
        if (s.count({a, b}) == 0) {
            adj[a].push_back(b);
            adj[b].push_back(a);
            s.insert({a, b});
            s.insert({b, a});
        }
    }
    memset(vis, false, sizeof vis);
    int ans = INT_MIN;
    for (int i = 1; i <= n; ++i) {
        if (!vis[i]) {
            x = 0;
            dfs(i);
            ans = max(ans, x);
        }
    }
    cout << ans << "\n";
}