#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 5005
#define M 10005
int n,m;
struct edge{int v,next;edge(){}edge(int v,int next):v(v),next(next){}}edgs[M<<2];
int head[N],idx=1;
int dfn[N],low[N],dfnn;
bool kill[M<<1];
int from[N],dcc;
int dcc_head[N];
bool vis[N],vis2[N];
int in[N];
inline void add(int u,int v){edgs[++idx]={v,head[u]};head[u]=idx;}
inline void dcc_add(int u,int v){edgs[++idx]={v,dcc_head[u]};dcc_head[u]=idx;}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++dfnn;
bool flag=1;
for(int edg=head[u];edg;edg=edgs[edg].next)
{
int v=edgs[edg].v;
if(dfn[v])
{
if(v==fa&&flag)
flag=0;
else low[u]=min(low[u],dfn[v]);
}
else
{
tarjan(v,u);
low[u]=min(low[u],dfn[v]);
if(dfn[u]<low[v])
kill[edg]=kill[edg^1]=1;
}
}
}
void dfs(int u,int fromm)
{
vis[u]=1;
from[u]=fromm;
for(int edg=head[u];edg;edg=edgs[edg].next)
{
int v=edgs[edg].v;
if(kill[edg])
{
dcc_add(from[u],v);
continue;
}
if(vis[v])
continue;
dfs(v,fromm);
}
}
signed main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
if(u==v)
continue;
add(u,v);add(v,u);
}
for(int i=1;i<=n;++i)
if(!dfn[i])
tarjan(i,0);
for(int i=1;i<=n;++i)
if(!vis[i])
dfs(i,++dcc);
for(int i=1;i<=dcc;++i)
{
memset(vis2,0,sizeof vis2);
for(int edg=dcc_head[i];edg;edg=edgs[edg].next)
{
int v=from[edgs[edg].v];
in[v]+=1-vis2[v];
vis2[v]=1;
}
}
int cnt=0;
for(int i=1;i<=dcc;++i)
cnt+=(in[i]==1);
printf("%d",(cnt+1>>1));
return 0;
}