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 Kotlin (1.3.71) (judge verdict: Time Limit Exceeded)

fun main() {
    val (_, m) = nextIntList()
    val groupList = mutableListOf<MutableSet<Int>>()
    val groupMap = mutableMapOf<Int, Int>()
    repeat(m) {
        val (a, b) = nextIntList()
        val ia = groupMap[a] ?: -1
        val ib = groupMap[b] ?: -1

        when {
            ia == -1 && ib == -1 -> {
                groupList.add(mutableSetOf(a, b))
                groupMap[a] = groupList.lastIndex
                groupMap[b] = groupList.lastIndex
            }
            ia == -1 -> {
                groupList[ib].add(a)
                groupMap[a] = ib
            }
            ib == -1 -> {
                groupList[ia].add(b)
                groupMap[b] = ia
            }
            ia == ib -> Unit
            else -> {
                // merge
                val group = groupList[ib]
                groupList[ia].addAll(groupList[ib])
                // groupList.removeAt(ib)
                group.forEach { num ->
                    groupMap[num] = ia
                }
            }
        }
    }
    println(groupMap.values.map { groupList[it].size }.max() ?: 1)
}

// # Utils
// ## Input
fun next() = readLine()!!
fun nextInt() = next().toInt()
fun nextLong() = next().toLong()
fun nextDouble() = next().toDouble()
fun nextList() = next().split(" ")
fun nextIntList() = next().split(" ").map(String::toInt)
fun nextLongList() = next().split(" ").map(String::toLong)
fun nextDoubleList() = next().split(" ").map(String::toDouble)

// ## Array
inline fun <reified T> sizedArray(size: Int, default: T) = Array(size) { default }
inline fun <reified T> sized2DArray(row: Int, column: Int, default: T) = Array(row) { Array(column) { default } }

// ## mod^-1
//    [NOTE] CANNOT use this for 0, mod, 2mod, 3mod ...(return wrong value)
fun modinv(num: Long, mod: Long): Long {
    var a = num
    var b = mod
    var u = 1L
    var v = 0L
    while (b > 0) {
        val t = a.div(b)
        a -= t * b
        a = b.also { b = a } // swap a and b
        u -= t * v
        u = v.also { v = u } // swap u and v
    }
    u %= mod
    if (u < 0) u += mod
    return u
}