#include<iostream>
using namespace std;
const int N = 1e5+10;
int f[N],g[N];
int find(int x)
{
if(f[x]!=x) return f[x]=find(f[x]);
else return f[x];
}
int main()
{
int n,m;
cin>>n>>m;
for(int i = 1;i<=n;i++) f[i]=i;
while(m--)
{
int a,b;
cin>>a>>b;
f[find(a)]=find(b);
}
int ans = 0,maxnum = 0;
for(int i = 1;i<=n;i++)
{
if(f[i]==i) ans++;//ans 用于统计连通分量的数量,遍历所有节点,若 f[i] 等于 i,说明 i 是一个连通分量的根节点,ans 加 1。
g[find(i)]++;//g[find(i)] 记录每个连通分量的节点数量,更新 maxnum 为最大连通分量的节点数。
if(g[find(i)]>maxnum) maxnum = g[find(i)];
}
cout<<ans<<' '<<maxnum<<endl;
return 0;
}