class UnionFind
  attr_accessor :parent, :rank, :size

  def initialize(size)
    @size = size
    @parent = size.times.to_a
    @rank = Array.new(size, 0)
  end

  def root(x)
    if parent[x] == x
      x
    else
      parent[x] = root(parent[x])
    end
  end

  def same?(x, y)
    root(x) == root(y)
  end

  def merge(x, y)
    x_root = root(x)
    y_root = root(y)

    return if x_root == y_root

    if rank[x_root] < rank[y_root]
      parent[x_root] = y_root
      rank[x_root] = nil
    else
      parent[y_root] = x_root
      rank[y_root] = nil
      rank[x_root] += 1 if rank[x_root] == rank[y_root]
    end
  end

  def shortage_all
    size.times { root(_1) }
  end
end

N, M = gets.split.map(&:to_i)
uf = UnionFind.new(N)

m = 0
M.times do
  a, b = gets.split.map(&:to_i)
  a -= 1
  b -= 1
  uf.merge(a,b)
end
uf.shortage_all
puts uf.parent.tally.values.max
