//用并查集将块缩成点
#include<iostream>
#include<vector>
using namespace std;
vector<int>list[5001];
int low[5001];
int d[5001],dep[5001];
int color[5001];
int n,m;
int bridge[10001][2];
int p[5001],rank[5001],cnt,tol,num=0;
int ncon,belong[5001];
void Init()
{
int i;
for(i=1;i<=n;i++)
{
p[i]=i;
rank[i]=0;
}
}
int Find(int x)
{
if(x!=p[x])
p[x]=Find(p[x]);
return p[x];
}
int Union(int x,int y)
{
int a=Find(x);
int b=Find(y);
if(rank[a]>rank[b])
{
p[b]=a;
}
else
{
p[a]=b;
if(rank[a]==rank[b])
{
rank[b]++;
}
}
return 0;
}
int DFS(int u,int fa,int t)
{
color[u]=1;
dep[u]=low[u]=t;
tol=0;
int tofa=0;
int i,v;
for(i=0;i<list[u].size();i++)
{
v=list[u][i];
if(color[v]==0)
{
DFS(v,u,t+1);
tol++;
low[u]=min(low[u],low[v]);
if(low[v]<=dep[u])
Union(u,v);
if(low[v]>dep[u])
{
bridge[num][0]=u;
bridge[num++][1]=v;
}
}
else if(v!=fa||tofa)
{
low[u]=min(low[u],dep[v]);
}
if(v==fa) tofa=1;
}
return 0;
}
int DC()
{
int i;
for(i=1;i<=n;i++)
{
belong[i]=-1;
}
for(i=1;i<=n;i++)
{
int k=Find(i);
if(belong[k]==-1)
belong[k]=++ncon;
belong[i]=belong[k];
}
for(i=0;i<num;i++)
{
d[belong[bridge[i][0]]]++;
d[belong[bridge[i][1]]]++;
}
for(i=1;i<=ncon;i++)
{
if(d[i]==1)
cnt++;
}
return (cnt+1)/2;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
cnt=0;
num=0;
memset(list,0,sizeof(list));
memset(d,0,sizeof(d));
memset(dep,0,sizeof(dep));
memset(low,0,sizeof(low));
memset(color,0,sizeof(color));
int a,b;
while(m--)
{
scanf("%d%d",&a,&b);
list[a].push_back(b);
list[b].push_back(a);
}
Init();
int i;
for(i=1;i<=n;i++)
{
if(!color[i])
DFS(i,-1,1);
}
printf("%d\n",DC());
}
system("pause");
return 0;
}