tarjan求割边
#include <bits/stdc++.h>
using namespace std;
const int N=3e5+5;
struct data
{
int to,next;
} tu[600000+5];
int head[N],low[N],dfn[N];
int ip;
int step;
int ans;
int n,m;
void init()
{
ip=0;
step=1;///遍历的步数
memset(head,-1,sizeof(head));
memset(dfn, 0, sizeof(dfn));
}
void add(int u,int v)
{
tu[ip].to=v,tu[ip].next=head[u],head[u]=ip++;
}
void tarjan(int u,int pre)
{
dfn[u] = low[u] = step++;
for(int i = head[u]; i!=-1 ; i=tu[i].next)
{
int to = tu[i].to;
if(!dfn[to])
{
tarjan(to,u);
low[u]=min(low[u],low[to]);
if(low[to]>dfn[u])
ans++;
}
else if(to!=pre)
low[u]=min(low[u],dfn[to]);
}
}
int main(int argc, char const *argv[])
{
/* code */
scanf("%d%d",&n,&m);
init();
for(int i=0;i<m;i++)
{
int u,v;scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
tarjan(1,-1);
cout<<m-ans<<endl;
return 0;
}