rt。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
const int N=15005;
int n,m,x,y,sigh=0,vis[N],DFN[N],Low[N],cnt=0;
vector<int> ditu[N];
struct bian{
int x,y;
bool operator<(const bian a)const{
}
};
map<bian,bool> mp;
void DFS(int u){
DFN[u]=Low[u]=++sigh;//DFN为遍历次序(时间戳),Low为向上可回溯到的最早的点
for(auto ed:ditu[u]){//枚举所有点
if(!mp[{u,ed}]){//有边且未被标记过
mp[{u,ed}]=1;
vector<int>::iterator it=find(ditu[ed].begin(),ditu[ed].end(),u);
ditu[ed].erase(it);
if(vis[ed]==0){//该点没有到过(该边为父子边)
vis[ed]=1;
DFS(ed);//延DFS树继续递归
Low[u]=min(Low[u],Low[ed]);//尝试更新u向上可回溯到的最早的点
if(Low[ed]>=DFN[u]){//无法回溯得更高
cnt++;//uv是割边
}
}
else Low[u]=min(Low[u],DFN[ed]);//否则该边为返祖边,尝试更新u向上可回溯到的最早的点
}
}
}
int main(){
while(cin>>n>>m){
sigh=0,cnt=0;
memset(vis,0,sizeof(vis));
memset(DFN,0,sizeof(DFN));
memset(Low,0,sizeof(Low));
for(int i=1;i<=N;i++) ditu[i].clear();
if(n==0 && m==0) break;
for(int i=1;i<=m;i++){
cin>>x>>y;
ditu[x].push_back(y);
ditu[y].push_back(x);
}
vis[1]=1;
DFS(1);
cout<<cnt<<"\n";
}
return 0;
}