using namespace std;
#include<bits/stdc++.h>
#define BEGIN ios_base::sync_with_stdio(0);cin.tie(0)
#define END return EXIT_SUCCESS
#define FOR(I,A,B) for((I)=(A);(I)<(B);(I)++)
#define REP(I,N) FOR(I,0,N)
#define UP(I,A,B) for((I)=(A);(I)<=(B);(I)++)
#define DW(I,A,B) for((I)=(A);(I)>=(B);(I)--)
#define IN(P) cin>>(P)
#define IN2(P1,P2) cin>>(P1)>>(P2)
#define IN3(P1,P2,P3) cin>>(P1)>>(P2)>>(P3)
#define INS(I,N,V) REP(I,N) cin>>V[I]
#define INS2(I,N,V1,V2) REP(I,N) cin>>V1[I]>>V2[I];
#define INS3(I,N,V1,V2,V3) REP(I,N) cin>>V1[I]>>V2[I]>>V3[I];
#define OUT(P) cout<<P<<endl
#define OUT2(P1,P2) cout<<P1<<" "<<P2<<endl
#define OUT3(P1,P2,P3) cout<<P1<<" "<<P2<<" "<<P3<<endl
#define OUTS(I,N,V) REP(I,N) cout<<V[i]<<endl
#define ALL(C) (C).begin(),(C).end()
#define RALL(C) (C).rbegin(),(C).rend()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
typedef unsigned long ul;
const ul INF = 1LL<<60;

#define DEBUG 0
typedef pair<int,int> P;
int V,E;
vector<vector<int> > G;
vector<int> depth;
vector<int> cnt;
vector<bool> visited;
vector<P> ans;

void dfs(int now,int prev){
  #if DEBUG
  cout<<"dfs start"<<endl;
  printf("now:%d prev:%d\n",now,prev);
  cout<<"【before】visited"<<endl;
  for(int i=0;i<V;i++)cout<<visited[i];
  cout<<endl;
  #endif
  visited[now]=true;
  #if DEBUG
  cout<<"【after】visited"<<endl;
  for(int i=0;i<V;i++)cout<<visited[i];
  cout<<endl;
  #endif
  for(int i=0;i<(int)G[now].size();i++){
    int to=G[now][i];
    #if DEBUG
    cout<<"to:"<<to<<endl;
    #endif
    if(to==prev){
      #if DEBUG
      cout<<"to=prev"<<endl;
      #endif
      continue;
    }
    if(!visited[to]){
      #if DEBUG
      cout<<"visit 【to】 at first"<<endl;
      printf("【before】depth[now]:%d depth[to]:%d\n",depth[now],depth[to]);
      #endif
      depth[to]=depth[now]+1;
      #if DEBUG
      printf("【after】depth[now]:%d depth[to]:%d\n",depth[now],depth[to]);
      #endif
      dfs(to,now);
      #if DEBUG
      printf("【before】cnt[now]:%d cnt[to]:%d\n",cnt[now],cnt[to]);
      #endif
      cnt[now]+=cnt[to];
      #if DEBUG
      printf("【after】cnt[now]:%d cnt[to]:%d\n",cnt[now],cnt[to]);
      #endif
      if(cnt[to]==0){
        ans.push_back(P(min(now,to),max(now,to)));
        #if DEBUG
        printf("bridge:%d %d\n",min(now,to),max(now,to));
        #endif
      }
    }else if(depth[to]<depth[now]){
      #if DEBUG
      printf("depth[to]:%d depth[now]:%d\n",depth[to],depth[now]);
      printf("【before】cnt[now]:%d cnt[to]:%d\n",cnt[now],cnt[to]);
      #endif
      cnt[now]++;
      cnt[to]--;
      #if DEBUG
      printf("【before】cnt[now]:%d cnt[to]:%d\n",cnt[now],cnt[to]);
      #endif
    }
  }
  #if DEBUG
  cout<<"dfs end"<<endl;
  #endif
}

inline void solve(){
  scanf("%d %d",&V,&E);
  G.resize(V);
  depth.resize(V);
  cnt.resize(V);
  visited.resize(V);
  for(int i=0;i<E;i++){
    int a,b;
    scanf("%d %d",&a,&b);
    G[--a].push_back(--b);
    G[b].push_back(a);
  }
  dfs(0,-1);
  printf("%d\n",(int)ans.size());
}

int main(int argc,char**argv){
  BEGIN;
  solve();
  END;
}


Measured memory_bytes: 256