```cpp
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 10010
#define M 100010
using namespace std;
inline int read(){
int a=0,x=1;char ch=getchar();
for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')x=-x;
for(;ch>='0'&&ch<='9';ch=getchar())a=a*10+ch-'0';
return x*a;
}
int now[N],dfn[N],low[N];
int pre[M],son[M],cnt,ans;
int n,m,tot;
inline void addx(int x,int y){
pre[++tot]=now[x];
son[tot]=y;
now[x]=tot;
}
struct Stack{
int v[100000],tot,bl[100000];
int top(){if(!tot)return -1;return v[tot];}
void pop(){if(!tot)return;bl[v[tot]]=0;tot--;}
void push(int a){v[++tot]=a;bl[v[tot]]=1;}
bool in(int a){return bl[a];}
}st;
struct union_find_set{
}bcj;
void tarjan(int u,int f){
low[u]=dfn[u]=++cnt;st.push(u);
for(int p=now[u];p;p=pre[p]){
int v=son[p];
if(!dfn[v]){
tarjan(v,u);low[u]=min(low[u],low[v]);
}
else if(st.in(v))low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
int c=1;
while(st.top()!=u)st.pop(),c++;st.pop();
if(c-1)ans++;
}
}
int main(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
addx(x,y);addx(y,x);
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i,0);
printf("%d\n",ans);
return 0;
}
```
by zxy123 @ 2017-11-04 16:24:01