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 Go (1.14.1) (judge verdict: Accepted)

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func nextFloat64() float64 {
	sc.Scan()
	i, e := strconv.ParseFloat(sc.Text(), 64)
	if e != nil {
		panic(e)
	}
	return i
}

func nextString() string {
	sc.Scan()
	return sc.Text()
}

func contain(i int, as []int) bool {
	for _, a := range as {
		if a == i {
			return true
		}
	}
	return false
}

type UnionFind struct {
	Par map[int]int
}

func NewUnionFind(n int) *UnionFind {
	par := make(map[int]int)
	for i := 0; i < n; i++ {
		par[i] = -1
	}
	return &UnionFind{
		Par: par,
	}
}

func (u *UnionFind) Root(x int) int {
	c := u.Par[x]
	if c < 0 {
		return x
	}
	u.Par[x] = u.Root(u.Par[x])
	return u.Par[x]
}

func (u *UnionFind) Unite(x, y int) bool {
	x = u.Root(x) //xの根をrx
	y = u.Root(y) //yの根をry
	if x == y {
		return false
	} //xとyの根が同じ(=同じ木にある)時はそのまま
	if u.Par[x] > u.Par[y] {
		tmp := x
		x = y
		y = tmp
	}
	u.Par[x] += u.Par[y]
	u.Par[y] = x
	return true
}

func (u *UnionFind) Same(x, y int) bool { // 2つのデータx, yが属する木が同じならtrueを返す
	rx := u.Root(x)
	ry := u.Root(y)
	return rx == ry
}

func (u *UnionFind) Size(x int) int {
	n := u.Root(x)
	return -u.Par[n]
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

func main() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(nil, 100000000)

	n, m := nextInt(), nextInt()

	uf := NewUnionFind(n)

	for i := 0; i < m; i++ {
		k, v := nextInt()-1, nextInt()-1
		uf.Unite(k, v)
	}

	ans := 0
	for i := 0; i < n; i++ {
		ans = max(ans, uf.Size(i))
	}
	fmt.Println(ans)
}