#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define size 5000
struct edge
{
int to,next;
} e[500000];
int v[size],cnt;
void insert(int from,int to)
{
e[cnt].to=to;
e[cnt].next=v[from];
v[from]=cnt++;
}
int low[size],dfn[size],index;
void tarjan(int id,int from)
{
low[id]=dfn[id]=++index;
bool flag=false;
for(int i=v[id];i!=-1;i=e[i].next)
if(e[i].to==from&&!flag) flag=true;
else
{
if(!dfn[e[i].to]) tarjan(e[i].to,id);
low[id]=min(low[id],low[e[i].to]);
}
}
void solve(int n)
{
index=0;
memset(dfn,0,sizeof(dfn));
for(int i=0;i<n;i++)
if(!dfn[i]) tarjan(i,-1);
}
int r,f,a,b,ans[size];
int main()
{
while(scanf("%d%d",&f,&r)!=EOF)
{
memset(v,-1,sizeof(v));
cnt=0;
while(r--)
{
scanf("%d%d",&a,&b);
insert(a-1,b-1);
insert(b-1,a-1);
}
solve(f);
memset(ans,0,sizeof(ans));
int re=0;//用tarjan的变形算法求出low数组,low相同的点就在一个边连通分量中
for(int i=0;i<f;i++)
for(int j=v[i];j!=-1;j=e[j].next)
if(low[i]!=low[e[j].to]) ans[low[i]]++;
for(int i=0;i<=f;i++) if (ans[i]==1) re++;
printf("%d/n",(re+1)/2);
}
return 0;
}