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 Pascal (FPC 2.6.2) (judge verdict: Accepted)

uses math;
var
  head,next,d,dfn,low,a:array[0..200005]of longint;
  insta:array[0..200005]of boolean;
  n,m,i,x,y,k,num,s,son,ans:longint;
procedure add(x,y:longint);
begin
  inc(num);
  d[num]:=y;
  next[num]:=head[x];
  head[x]:=num;
end;
procedure dfs(u,fa:longint);
var
  v,ll:longint;
  flag:boolean;
begin
  inc(s);
  dfn[u]:=s;
  low[u]:=s;
  ll:=head[u];
  insta[u]:=true;
  flag:=true;
  while ll<>0 do
  begin
    v:=d[ll];
    if v=fa then
    begin
      ll:=next[ll];
      continue;
    end;
    if dfn[v]=0 then
    begin
      dfs(v,u);
      low[u]:=min(low[u],low[v]);
      if low[v]>dfn[u] then
        inc(ans);
    end else
      low[u]:=min(low[u],dfn[v]);
    ll:=next[ll];
  end;
  insta[u]:=false;
end;
procedure qsort(l,r:longint);
var
  i,j,k,t:longint;
begin
  i:=l;
  j:=r;
  k:=(i+j) div 2;
  t:=a[k];
  a[k]:=a[i];
  while i<j do
  begin
    while (i<j) and (a[j]>t) do
      dec(j);
    if i<j then
    begin
      a[i]:=a[j];
      inc(i);
    end;
    while (i<j) and (a[i]<t) do
      inc(i);
    if i<j then
    begin
      a[j]:=a[i];
      dec(j);
    end;
  end;
  a[i]:=t;
  if i-1>l then
    qsort(l,i-1);
  if i+1<r then
    qsort(i+1,r);
end;
begin
  readln(n,m);
  for i:=1 to m do
  begin
    readln(x,y);
    add(x,y);
    add(y,x);
  end;
  for i:=1 to n do
    if dfn[i]=0 then
      dfs(i,0);
  writeln(ans);
end.