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 PHP7 (7.0.15) (judge verdict: Accepted)

<?php
list($n, $m) = explode(" ", trim(fgets(STDIN)));

for($i = 0 ; $i < $m; $i++){
    $link[] = explode(" ", trim(fgets(STDIN)));
}

$count = 0;
for($i = 0 ; $i < $m; $i++){
    $uft = new UFT($n);
    for($j = 0 ; $j < $m; $j++){
        if($i != $j){
            $uft->unite($link[$j][0], $link[$j][1]);
        }
    }
    if($uft->getRoot($link[$i][0]) <> $uft->getRoot($link[$i][1])){
        $count++;
    }
}
echo $count;

class UFT{
    public $parent;
    public $size;
    public $rank;
    public function __construct($size){
        for($i = 1; $i <= $size; $i++){
            $this->size[$i] = 1;
            $this->rank[$i] = 1;
            $this->parent[$i] = 0;
        }
    }
    public function dump(){
        o("--------------");
        o($this->parent);
        o($this->size);
        o($this->rank);
    }
    public function getRoot($i){
        if($this->parent[$i] == 0){
            return $i;
        }else{
            return $this->getRoot($this->parent[$i]);
        }
    }
    public function unite($i, $j){
        $rootI = $this->getRoot($j);
        $rootJ = $this->getRoot($i);
        if($rootJ == $rootI)return false;//元から同じグループ
        if($this->rank[$rootI] > $this->rank[$rootJ])list($rootI, $rootJ) = [$rootJ, $rootI];//Rank(J)>Rank(I)に揃えておく
        $this->parent[$rootI] = $rootJ;
        if($this->rank[$rootI] == $this->rank[$rootJ]){
            $this->rank[$rootJ]++;
        }
        $this->size[$rootJ]+=$this->size[$rootI];
        $this->size[$rootI] = '*';//不要な情報となるので潰す/デバッグ出力向けに*を入れている
        $this->rank[$rootI] = '*';//同上
    }
    public function size($i){return $this->size[$this->getRoot($i)];}
    public function isUnion($i, $j){return $this->getRoot($i) == $this->getRoot($j);}
}