local UnionFind={}

UnionFind.create=function(self,n)
    self.par={}
    self.rank={}
    self.size={}
    for i=1,n do
        self.par[i]=i
        self.rank[i]=1
        self.size[i]=1
    end
end

UnionFind.getroot=function(self,x)
    local nx=x
    while self.par[x]~=x do
        x=self.par[x]
    end
    while self.par[nx]~=x do
        self.par[nx],nx=x,self.par[nx]
    end
    return x
end

UnionFind.same=function(self,x,y)
    return self:getroot(x)==self:getroot(y)
end

UnionFind.unite=function(self,x,y)
    x=self:getroot(x)
    y=self:getroot(y)
    if x==y then
        return
    end
    if self.rank[x]>self.rank[y] then
        x,y=y,x
    elseif self.rank[x]==self.rank[y] then
        self.rank[x]=self.rank[x]+1
    end
    self.par[x]=y
    self.size[y]=self.size[y]+self.size[x]
end

UnionFind.getsize=function(self,x)
    return self.size[self:getroot(x)]
end

UnionFind.new=function(self,n)
    local obj={}
    setmetatable(obj,{__index=UnionFind})
    obj:create(n)
    return obj
end

----------

local n,m=io.read("n","n")
local uf=UnionFind:new(n)
for i=1,m do
    local a,b=io.read("n","n")
    uf:unite(a,b)
end

local max=0
for i=1,n do
    max=math.max(max,uf:getsize(i))
end
print(max)