Problem:
Score : 300 points

Problem Statement

You are given an undirected connected graph with N vertices and M edges that does not contain self-loops and double edges.

The i-th edge (1 \leq i \leq M) connects Vertex a_i and Vertex b_i.

An edge whose removal disconnects the graph is called a bridge.

Find the number of the edges that are bridges among the M edges.

Notes

A self-loop is an edge i such that a_i=b_i (1 \leq i \leq M).

Double edges are a pair of edges i,j such that a_i=a_j and b_i=b_j (1 \leq i<j \leq M).

An undirected graph is said to be connected when there exists a path between every pair of vertices.

Constraints

2 \leq N \leq 50

N-1 \leq M \leq min(N(N−1)⁄2,50)

1 \leq a_i<b_i \leq N

The given graph does not contain self-loops and double edges.

The given graph is connected.

Input

Input is given from Standard Input in the following format:

N M
a_1 b_1
a_2 b_2
:
a_M b_M

Output

Print the number of the edges that are bridges among the M edges.

Sample Input 1

7 7
1 3
2 7
3 4
4 5
4 6
5 6
6 7

Sample Output 1

4

The figure below shows the given graph:

The edges shown in red are bridges. There are four of them.

Sample Input 2

3 3
1 2
1 3
2 3

Sample Output 2

0

It is possible that there is no bridge.

Sample Input 3

6 5
1 2
2 3
3 4
4 5
5 6

Sample Output 3

5

It is possible that every edge is a bridge.

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

// ABC 040 C
#include<bits/stdc++.h>
 
using namespace std;
//container util
//------------------------------------------
#define REP(i,n) for(int (i)=0;(i)<(n);(i)++)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)

#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())

#define SORT(c) sort((c).begin(),(c).end())
#define RSORT(c) sort((c).begin(),(c).end(),greater<int>())

#define PB(a) push_back(a)

#define ALL(x) (x).begin(),(x).end()
#define MAX_EL(c) *max_element((c).begin(),(c).end())
#define MIN_EL(c) *min_element((c).begin(),(c).end())
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<long long> VL;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef long long LL;
typedef string str;
 
//constant
//--------------------------------------------
const double EPS = 1e-10;
const double PI  = acos(-1.0);
//debug
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

//-----------------------------------------
//Groval variables
const int nmax = 50;
bool graph[nmax][nmax];
//------------------------------------------
void dfs(int v,int N,bool visited[nmax]){
  visited[v]=true;
  REP(i,N){
    if(graph[v][i]==false) continue;
    if(visited[i]) continue;
    dfs(i,N,visited);
  }
}
//------------------------------------------

int main(){
// magic spell------------------------------
  cin.tie(0);
  ios::sync_with_stdio(false);
//------------------------------------------

  int n,m,ans=0;
  bool visited[nmax];
  cin >> n >> m;
  int a[nmax],b[nmax];
  REP(i,m){
    cin >> a[i]>> b[i];
    a[i]--;b[i]--;
    graph[a[i]][b[i]]=graph[b[i]][a[i]]=true;
  }
  REP(i,m){
    graph[a[i]][b[i]]=graph[b[i]][a[i]]=false;
    REP(j,n) visited[j]=false;
    dfs(0,n,visited);
    bool isBridge = false;
    REP(j,n){
      if(!visited[j]) isBridge=true;
    }
    if(isBridge) ans++;
    graph[a[i]][b[i]]=graph[b[i]][a[i]]=true;
  }

  cout << ans << endl;
  return 0;
}