// 题意是要求在加完一条边后 使得桥最小
// 求桥 缩 边-连通分量 变成一颗树 然后求树的直径
// 看到这题是思路非常明确的
// 然后爆栈的问题一直困扰着我
// 然后我发现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\n",bcc-ans-1); } return 0; }