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# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace atcoder
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var buffer = Console.ReadLine().Split();
            var N = int.Parse(buffer[0]);
            var M = int.Parse(buffer[1]);

            UnionFind uf = new UnionFind(N);
            for (int i = 0; i < M; i++)
            {
                buffer = Console.ReadLine().Split();
                var A = int.Parse(buffer[0]);
                var B = int.Parse(buffer[1]);
                A -= 1; B -= 1;
                uf.Unite(A, B);
            }

            int ans = 0;
            for (int i = 0; i < N; i++)
                ans = Math.Max(ans, uf.Size(i));

            Console.WriteLine(ans);
        }
    }

    class UnionFind
    {
        IList<int> list;

        public UnionFind(int n)
        {
            list = Enumerable.Repeat(-1, n).ToList();
        }

        public int Root(int x)
        {
            if (this.list[x] < 0) return x;
            return this.list[x] = Root(this.list[x]);
        }

        public bool Unite(int x, int y)
        {
            x = Root(x);
            y = Root(y);
            if (x == y) return false;
            if (this.list[x] > this.list[y]) Swap(ref x, ref y);
            this.list[x] += this.list[y];
            this.list[y] = x;
            return true;
        }

        public void Swap(ref int x, ref int y)
        {
            var tmp = x;
            x = y;
            y = tmp;
        }

        public int Size(int x)
        {
            return -this.list[Root(x)];
        }
    }
}