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 Rust (1.42.0) (judge verdict: Accepted)

use proconio::input;
use proconio::marker::{Chars, Usize1};
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused)]
const ALPHA_SMALL: [char; 26] = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
    't', 'u', 'v', 'w', 'x', 'y', 'z',
];
#[allow(unused)]
const ALPHA: [char; 26] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
    'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];

fn main() {
    input!(N: usize, M: usize);
    let mut g = vec![vec![]; N];
    for _ in 0..M {
        input!(a: Usize1, b: Usize1);
        g[a].push(b);
        g[b].push(a);
    }

    let cell = bfs(&g);
    let mut ans = 0;
    for &e in &cell {
        if ans < e {
            ans = e;
        }
    }

    println!("{}", ans + 1);
}

fn bfs(g: &Vec<Vec<usize>>) -> Vec<usize> {
    let mut ret = vec![];
    let N = g.len();
    let mut visited = vec![false; N];
    for i in 0..N {
        if visited[i] {
            continue;
        }
        let c = bfs_dist(N, &g, i, &mut visited);
        ret.push(c);
    }
    ret
}

fn bfs_dist(n: usize, g: &Vec<Vec<usize>>, start: usize, visit: &mut Vec<bool>) -> usize {
    let mut q = std::collections::VecDeque::new();
    let mut ret = 0;

    //init
    visit[start] = true;
    q.push_back(start);

    while let Some(now) = q.pop_front() {
        for &e in &g[now] {
            if !visit[e] {
                visit[e] = true;
                ret += 1;
                q.push_back(e);
            }
        }
    }
    ret
}