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 JavaScript (Node.js 12.16.1) (judge verdict: Accepted)

let input = require('fs').readFileSync('/dev/stdin', 'utf8')
// let input = require('fs').readFileSync('./sample_d.txt', 'utf8')
.split(/\n| /)
.slice(0 ,-1)
.map(item => parseInt(item))

const [N, M, ..._pair] = input

let r = new Array(N).fill(-1)

const root = x => {
    if (r[x] < 0) return x
    return r[x] = root(r[x])
}

const unite = (x, y) => {
    x = root(x)
    y = root(y)
    if (x == y) return false
    if (r[x] > r[y]) [x, y] = [y, x]
    r[x] += r[y]
    r[y] = x
    return true
}

const size = x => {
    return -r[root(x)]
}


for (let i=0; i<_pair.length; i+=2){
    unite(_pair[i]-1, _pair[i+1]-1)
}
 
//最大の友達集合を求める
let ans = 0
for ( let i=0; i<N; i++){
    ans = Math.max(ans, size(i));
}

console.log(ans)

// const [N, M, ..._pair] = input
// const pair = []
// for(let i=0; i<N; i++){
//     pair.push(new Array(N-i).fill(true))
// }

// for(let i=0; i<_pair.length; i+=2){
//     const a = [_pair[i], _pair[i+1]].sort()
//     pair[a[0]-1][a[1]-a[0]] = false
// }


// const member = [ new Set() ]

// pair[0].forEach( (item, index) => {
//     if(item) member[0].add(index+1)
//     else{
//         member.push(new Set())
//         member[member.length-1].add(index+1)
//     }
// } )

// for( let i=1; i<N; i++){
//     for( let j=1; j<pair[i].length; j++){
//         if(!pair[i][j]){
//             member.forEach( (sample, index) => {
//                 if( sample.has(i+1) && sample.has(i+j+1) ){
//                     sample.delete(i+j)
//                     if(member.length - 1 <= index) member.push(new Set())
//                     member[index+1].add(i+j)
//                 }
//             })
//         }
//     }
// }

// console.log(member.length)