#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
#include<algorithm>
#include<vector>
using namespace std;
const int N=3e5+9;
const int M=6e5+9;
struct node{
int last;
int to;
}e[M],e2[M];
int head[N],head2[N];
int cnt,cnt2;
int vis[N];
int dfn[N],low[N];
int c[N],poi;
bool bridge[M];
int n,m,dcc;
void add(int from,int to)
{
e[++cnt].last=head[from];
e[cnt].to=to;
head[from]=cnt;
}
void add2(int from,int to)
{
e2[++cnt2].last=head2[from];
e2[cnt2].to=to;
head2[from]=cnt2;
}
void tarjan(int u,int edge)
{
low[u]=dfn[u]=++poi;
for(int i=head[u];i;i=e[i].last)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]) bridge[i]=bridge[i^1]=1;
}
else if(i!=(edge^1)) low[u]=min(low[u],dfn[v]);
}
}
void dfs(int x)
{
c[x]=dcc;
for(int i=head[x];i;i=e[i].last)
{
int v=e[i].to;
if(c[v]||bridge[i]) continue;
dfs(v);
}
}
int maxdep,maxw;
void dfs2(int dep,int x,int fa)
{
cout<<dep<<endl;
if(dep>maxdep)
{
maxw=x;
maxdep=dep;
}
for(int i=head2[x];i;i=e2[i].last)
{
int v=e2[i].to;
if(v!=fa)
dfs2(dep+1,v,x);
}
}
int main()
{
scanf("%d%d",&n,&m);
cnt=1,cnt2=1;
for(int i=1;i<=m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)
if(!dfn[i]) tarjan(i,0);//缩点,找遍双
for(int i=1;i<=n;i++)
{
if(!c[i])
{
++dcc;
dfs(i);
}
}//缩点
for(int i=2;i<=cnt;i++)
{
int x=e[i^1].to;
int y=e[i].to;
if(c[i]==c[y]) continue;
add2(c[x],c[y]);
}
dfs2(0,1,0);
dfs2(0,maxw,0);
cout<<maxdep<<endl;
return 0;
}