// 题意是要求在加完一条边后 使得桥最小
// 求桥 缩 边-连通分量 变成一颗树 然后求树的直径
// 看到这题是思路非常明确的
// 然后爆栈的问题一直困扰着我
// 然后我发现ac的代码里面有 #pragma comment(linker, "/STACK:1024000000,1024000000")
// 这个东西 今天无意中看到题解 然后说hdu栈太小 标程都跪了、
// 我、、、、
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <math.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MOD 1000000007
#define maxn 2000100
#define maxm 200010
struct Edge{
int to;
int next;
Edge(){};
Edge(int u,int v){to=u;next=v;}
}E[maxn],EE[maxn];
int V[maxm],num;
int VV[maxm],nu;
int vi[maxm];
int pre[maxm];
int dfst,bcc;
int belong[maxm];
// bool tag[maxn];
int sta[maxm],s;
void init(int n){
dfst=0;
num=0;
bcc=0;
for(int i=1;i<=n;i++){
V[i]=-1;
pre[i]=0;
}
}
void add(int u,int v){
E[num].to=v;
E[num].next=V[u];
V[u]=num++;
}
void Treeadd(int u,int v){
EE[nu].to=v;
EE[nu].next=VV[u];
VV[u]=nu++;
}
int dfs(int u,int fa){
int lowu,cnt=0;
lowu=pre[u]=++dfst;
int v,e;
sta[s++]=u;
for(e=V[u];e!=-1;e=E[e].next){
v=E[e].to;
if(!pre[v]){
int lowv=dfs(v,u);
lowu=min(lowu,lowv);
}
else if(v==fa){ // 处理重边
if(cnt) lowu=min(lowu,pre[v]);
cnt++;
}
else lowu=min(lowu,pre[v]);
}
if(pre[u]==lowu){
int x;
bcc++;
do
{
x = sta[--s];
belong[x] = bcc;
}while(x!=u);
}
return lowu;
}
int rc[maxn][2];//,in[maxm];// 记录边 和 缩点后新节点度数
int ans;
int dfstree(int u){
// printf("u= %d ",u);
vi[u]=true;
int e,v;
int max1=0,max2=0,tp;
for(e=VV[u];e!=-1;e=EE[e].next){
v=EE[e].to;
if(vi[v]) continue;
tp=dfstree(v);
if(tp>max1){
max2=max(max1,max2);
max1=tp;
}
else if(tp>max2)
max2=tp;
}
ans=max(ans,max1+max2);
return max1+1;
}
int main()
{
int F,R;
int u,v;
int i,j;
while(scanf("%d %d",&F,&R),F|R){
init(F);
for(i=1;i<=R;i++){
scanf("%d %d",&u,&v);
rc[i][0]=u;rc[i][1]=v;
if(u==v) continue;
add(u,v);
add(v,u);
}
s=0;
dfs(1,-1);
for(i=1;i<=bcc;i++) vi[i]=0,VV[i]=-1;
nu=0;
for(i=1;i<=R;i++)
{
u=belong[rc[i][0]];
v=belong[rc[i][1]];
if(u!=v){
Treeadd(u,v);
Treeadd(v,u);
}
}
ans=0;
dfstree(1);
printf("%d
",bcc-ans-1);
}
return 0;
}