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 static System.Console;
using System.Collections.Generic;

namespace abc177
{
    class Program
    {
        static void Main()
        {
            var nm = ReadLine().Split(' ');
            var n = int.Parse(nm[0]);
            var m = int.Parse(nm[1]);
            var r = new Random();
            var friends = new int[m][];
            for (var i = 0; i < m; ++i)
            {
                var ab = ReadLine().Split(' ');
                friends[i] = new int[] { int.Parse(ab[0]), int.Parse(ab[1]) };
            }
            if (m == 0)
            {
                WriteLine(1);
            }
            else
            {
                WriteLine(MaxGroupSize(n, friends));
            }
        }
        static int MaxGroupSize(int n, int[][] friends)
        {
            // group references
            var gref = new List<int>[n + 1];
            var ftree = new HashSet<int>[n + 1];
            for (var i = 0; i < friends.Length; ++i)
            {
                var a = friends[i][0];
                var b = friends[i][1];
                if (ftree[a] == null)
                {
                    ftree[a] = new HashSet<int>();
                }
                ftree[a].Add(b);
                if (ftree[b] == null)
                {
                    ftree[b] = new HashSet<int>();
                }
                ftree[b].Add(a);
            }

            var dp = new int[n + 1];
            for (var i = 1; i < n; ++i)
            {
                if (dp[i] == 0)
                {
                    var friendList = GetFriendList(i, ftree);
                    foreach (var friend in friendList)
                    {
                        dp[friend] = friendList.Count;
                    }
                }
            }

            var max = 0;
            foreach (var subTotal in dp)
            {
                max = Math.Max(max, subTotal);
            }
            return max;
        }
        static List<int> GetFriendList(int k, HashSet<int>[] ftree)
        {
            var q = new Queue<int>();
            q.Enqueue(k);
            var set = new HashSet<int>(){ k };
            while (q.Count > 0)
            {
                var i = q.Dequeue();
                if (ftree[i] != null)
                {
                    foreach (var friend in ftree[i])
                    {
                        if (!set.Contains(friend))
                        {
                            q.Enqueue(friend);
                            set.Add(friend);
                        }
                    }
                }
            }
            return new List<int>(set);
        }
    }
}