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 Ruby (2.7.1) (judge verdict: Accepted)

# Union-Find木
# 木構造を用いて、グループ分けを行うデータ構造
# 同じ木に属している場合、同じグループであるということになる
# 同じ木に属しているかどうかは、根となるノードが同じであるかどうかで判定をする
# 同じグループに属しているかどうかを、根ノードの値を参照するだけなのでO(1)で求められる
class UnionFind
  def initialize(size)
    @rank = Array.new(size, 0)
    @parent = Array.new(size, &:itself)
  end

  def tmp(n)
    arr = Array.new(n, 0)
    @parent.each do |num|
      arr[num] += 1
    end
    return arr.max
  end

  # node_xとnode_yを連結し、同じグループにする
  def unite(id_x, id_y)
    x_parent = get_parent(id_x)
    y_parent = get_parent(id_y)
    return if x_parent == y_parent

    if @rank[x_parent] > @rank[y_parent]
      @parent[y_parent] = x_parent
    else
      @parent[x_parent] = y_parent
      @rank[y_parent] += 1 if @rank[x_parent] == @rank[y_parent]
    end
  end

  # node_xの親ノードの番号を取得する
  def get_parent(id_x)
    @parent[id_x] == id_x ? id_x : (@parent[id_x] = get_parent(@parent[id_x]))
  end

  # node_x, node_yが連結しているか確かめる
  def same_parent?(id_x, id_y)
    get_parent(id_x) == get_parent(id_y)
  end
end

def input_n
  gets.to_i               # 単一整数
end

def input_s
  gets.chomp              # 文字列。chompを付けないと改行文字がついてくる
end

def input_a
  gets.split.map(&:to_i)  # スペースで区切られた複数の整数
end

def input_o(num)
  num.times.map { gets.to_i }  # 縦に並んだ複数の整数。たまにある
end

def output_f(num)
  puts sprintf("%.12f", num)
end

n, m = input_a
# 与えられた頂点数の大きさで宣言を行う
union = UnionFind.new(n + 1)

# ノード読み込み
a, b = m.times.map { gets.split.map(&:to_i) }.transpose
#p a
#p b
(m).times do |i|
  # 結合処理
  #  puts "#{i} #{a[i]} #{b[i]}"
  union.unite(a[i], b[i])
end

cnt = 0
(m).times do |i|
  # 判定処理
  if union.same_parent?(a[i], b[i])
    cnt += 1
  end
end
p union.tmp(n + 1)