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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.util.Scanner;

public class Main {
	public static int M;
	public static int N;
	public static boolean[][] A;
	public static boolean[] visited ;
public static void main(String[] args){
		Scanner sc = new Scanner(System.in);

		//A
		/*int a = sc.nextInt();
		int b = sc.nextInt();
		int c = sc.nextInt();
		if(a == c){
			System.out.println(b);
		}else if(b == c){
			System.out.println(a);
		}else if(b == a){
			System.out.println(c);
		}else{
			System.out.println("error!");
		}
	}*/

		//B
		/*int Height = sc.nextInt();
		int Weight = sc.nextInt();
		if(Height < 1 || Weight > 50){
			System.out.println("error!");
		}

		String[] S = new String[Height];
		for(int i = 0 ; i < Height ; i ++){
			S[i] = sc.next();
		}
		int BombCounter;
		for(int i = 0; i < Height ; i++){
			for(int j = 0; j < Weight ; j++){
				BombCounter = 0;
				if(i != 0 && j >= 1){
					if(S[i-1].charAt(j-1)== '#'){
						BombCounter ++;
					}
				}
				if(i != 0){
					if(S[i-1].charAt(j)== '#'){
						BombCounter ++;
					}
				}
				if(i != 0 && j <= Weight - 2){
					if(S[i-1].charAt(j+1)== '#'){
						BombCounter ++;
					}
				}
				if(j >= 1){
					if(S[i].charAt(j-1)== '#'){
						BombCounter ++;
					}
				}
				if(S[i].charAt(j)== '#'){
					BombCounter ++;
				}
				if(j <= Weight -2){
					if(S[i].charAt(j+1)== '#'){
						BombCounter ++;
					}
				}
				if(i <= Height -2 && j >= 1){
					if(S[i+1].charAt(j-1)== '#'){
						BombCounter ++;
					}
				}
				if(i <= Height-2){
					if(S[i+1].charAt(j)== '#'){
						BombCounter ++;
					}
				}
				if(i <= Height-2 && j <= Weight -2){
					if(S[i+1].charAt(j+1)== '#'){
						BombCounter ++;
					}
				}
				if(S[i].charAt(j)=='.'){
					System.out.print(BombCounter);
				}else{
					System.out.print("#");
				}
			}
			System.out.print("\n");
		}*/

		//C
		N = sc.nextInt();						//頂点の数の入力
		M = sc.nextInt();						//辺の数の入力
		int ans = 0;								//答えを保存する変数ans
		boolean bridge = false;
		A = new boolean[N][N];				//隣接行列A
		visited = new boolean[N];
		int[] a = new int[M];
		int[] b = new int[M];
		//Arrays.fill(A, false);					//Aの初期化
		for(int i = 0 ; i < M ; i++){
			a[i] = sc.nextInt();
			b[i] = sc.nextInt();
			a[i]--;
			b[i]--;
		}

		for(int i = 0; i < M; i++){
			A[a[i]][b[i]] = true;
			A[b[i]][a[i]] = true;
		}

		for(int i = 0 ; i < M ; i++){
			A[a[i]][b[i]] = false;
			A[b[i]][a[i]] = false;
			for(int x = 0 ; x < N ; x++){
				visited[x] = false;
			}
			bridge = false;
			DFS(N-1);
			for(int i2 = 0; i2 < N ; i2++){
				//System.out.println(i2 +","+visited[i2]);
				if(!visited[i2]){
					bridge = true;
				}
			}
			if(bridge){
				ans++;
			}
			A[a[i]][b[i]] = true;
			A[b[i]][a[i]] = true;
		}
		System.out.println(ans);

	}

	public static  void DFS(int a){
		visited[a] = true;
		for(int i = 0; i < N ; i++){
			if(A[a][i] && !visited[i]){
				DFS(i);
			}
		}
	}
}