#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;
}