qyliang/CodeNanoFix huggingface dataset:
# Buggy code:
n,m=map(int,input().split())
e=[]
for i in range(m):
    e.append(list(map(int,input().split())))
ans=0
for i in range(m):
    g=[[] for _ in range(n)]
    for j in range(m):
        if i==j:
            continue
        g[e[j][0]-1].append(e[j][1])
        g[e[j][1]-1].append(e[j][0])
    visited=[0]*n
    visited[0]=1
    q=[1]
    while len(q)>0:
        a=pop(q)
        visited[a-1]=1
        for k in g[a-1]:
            if visited[k-1]==0:
                q+=[k]
    if sum(visited)!=n:
        ans+=1
print(ans)
                    


# Fixed code:
n,m=map(int,input().split())
e=[]
for i in range(m):
    e.append(list(map(int,input().split())))
ans=0
for i in range(m):
    g=[[] for _ in range(n)]
    for j in range(m):
        if i==j:
            continue
        g[e[j][0]-1].append(e[j][1])
        g[e[j][1]-1].append(e[j][0])
    visited=[0]*n
    visited[0]=1
    q=[1]
    while len(q)>0:
        a=q.pop(0)
        visited[a-1]=1
        for k in g[a-1]:
            if visited[k-1]==0:
                q+=[k]
    if sum(visited)!=n:
        ans+=1
print(ans)
# Buggy code:
n,m=map(int,input().split())
g=[list() for _ in range(n+1)]
side=[list(map(int,input().split())) for i in range(m)]
for a,b in side:
	g[a].append(b)
	g[b].append(a)
cnt=0
def dfs(r,x,s):
	ed[x-1]=1
	for i in g[x]:
		if i!=r and s!={x,i}:dfs(x,i,s)
cnt=0
for i in range(m):
	ed=[0]*n
	dfs(0,1,set(side[i]))
	if 0 in ed:cnt+=1
print(cnt)

# Fixed code:
n,m=map(int,input().split())
g=[list() for _ in range(n+1)]
side=[list(map(int,input().split())) for i in range(m)]
for a,b in side:
	g[a].append(b)
	g[b].append(a)
cnt=0
def dfs(x,s):
	ed[x-1]=1
	for i in g[x]:
		if s!={x,i} and ed[i-1]==0:dfs(i,s)
cnt=0
for i in range(m):
	ed=[0]*n
	dfs(1,set(side[i]))
	if 0 in ed:cnt+=1
print(cnt)
# Buggy code:
n , m = map(int, input().split())
combis = [set(list(map(int, input().split()))) for i in range(m)]
count = 0
for i in range(m):
    combis_x = combis[0:i] + combis[i+1:m]
    islands = []
    for combi in combis_x:
        # init
        if not islands:
            islands.append(combi)
            continue
        # compare existed islands
        new_islands = islands
        joint_i = []
        for j, island in enumerate(islands):
            if not island.isdisjoint(combi):
                new_islands[j] = island | combi
                joint_i.append(j)
        else:
            if not joint_i:
                new_islands.append(combi)
            elif len(joint_i) == 2:
                new_islands[joint_i[0]] = new_islands[joint_i[0]] | new_islands[joint_i[1]]
                new_islands.pop(joint_i[1])
        islands = new_islands

    # judge
    if len(islands) == 1 and len(islands[0]) == n:
        continue
    elif len(islands) == 1 and len(islands[0]) == n - 1:
        count += 1
    else:# len(islands) == 2 and islands[0].isdisjoint(islands[1]):
        count += 1
print("count", count)



# Fixed code:
n , m = map(int, input().split())
combis = [set(list(map(int, input().split()))) for i in range(m)]
count = 0
for i in range(m):
    combis_x = combis[0:i] + combis[i+1:m]
    islands = []
    for combi in combis_x:
        # init
        if not islands:
            islands.append(combi)
            continue
        # compare existed islands
        new_islands = islands
        joint_i = []
        for j, island in enumerate(islands):
            if not island.isdisjoint(combi):
                new_islands[j] = island | combi
                joint_i.append(j)
        else:
            if not joint_i:
                new_islands.append(combi)
            elif len(joint_i) == 2:
                new_islands[joint_i[0]] = new_islands[joint_i[0]] | new_islands[joint_i[1]]
                new_islands.pop(joint_i[1])
        islands = new_islands

    # judge
    if len(islands) == 1 and len(islands[0]) == n:
        continue
    elif len(islands) == 1 and len(islands[0]) == n - 1:
        count += 1
    else:# len(islands) == 2 and islands[0].isdisjoint(islands[1]):
        count += 1
print(count)
# Buggy code:
from typing import List, Tuple


def main():
    n, m = map(int, input().split())
    g = []
    for _ in range(m):
        a, b = map(int, input().split())
        g.append((a, b))
    print(b(n, m, g))


def b(n: int, m: int, g: List[Tuple[int, int]]):
    ret = 0
    for i in range(m):
        v = set()
        w = []
        w.append(1)
        while w:
            now = w.pop()
            v.add(now)
            for j, node in enumerate(g):
                if j == i:
                    continue
                if node[0] == now and node[1] not in v:
                    w.append(node[1])
                elif node[1] == now and node[0] not in v:
                    w.append(node[0])
        if len(v) != n:
            ret += 1
    return ret


if __name__ == '__main__':
    main()


# Fixed code:
from typing import List, Tuple


def main():
    n, m = map(int, input().split())
    g = []
    for _ in range(m):
        a, b = map(int, input().split())
        g.append((a, b))
    print(bb(n, m, g))


def bb(n: int, m: int, g: List[Tuple[int, int]]):
    ret = 0
    for i in range(m):
        v = set()
        w = [1]
        while w:
            now = w.pop()
            v.add(now)
            for j, node in enumerate(g):
                if j == i:
                    continue
                if node[0] == now and node[1] not in v:
                    w.append(node[1])
                elif node[1] == now and node[0] not in v:
                    w.append(node[0])
        if len(v) != n:
            ret += 1
    return ret


if __name__ == '__main__':
    main()
# Buggy code:
def DFS(N, copyedge):
    matrix = [[] for i in range(M)]
    for a, b in copyedge:
        matrix[a].append(b)
        matrix[b].append(a)
        
    check = [True]*N
    check[0] = False
    Que = [0]

    while len(Que) != 0:
        now = Que.pop()
        for i in matrix[now]:
            if check[i] == True:
                check[i] = False
                Que.append(i)
    if True not in check:
        return 0
    else:
        return 1
            
        

ans = 0
N, M = map(int, input().split())
edge = []

for i in range(M):
    edge.append([int(i) - 1 for i in input().split()])
    
for i in range(M):
    copyedge = edge[:i] + edge[i+1:] 
    ans += DFS(N, copyedge)
print(ans)

# Fixed code:
def DFS(N, copyedge):
    matrix = [[] for i in range(N)]
    for a, b in copyedge:
        matrix[a] += [b]
        matrix[b] += [a]
    check = [True]*N
    check[0] = False
    Que = [0]
    
    while len(Que) != 0:
        now = Que.pop()
        for j in matrix[now]:
            if check[j] == True:
                check[j] = False
                Que.append(j)
    if check == [False]*N:
        return 0
    else:
        return 1       

ans = 0
N, M = map(int, input().split())
edge = []

for i in range(M):
    edge.append([int(i)-1 for i in input().split()])

for i in range(M):
    copyedge = edge[:i]+edge[i+1:]
    ans += DFS(N, copyedge)
print(ans)
# Buggy code:
import sys
input = sys.stdin.readline
from collections import deque

N,M=[int(val) for val in input().split()]
a=deque()
b=deque()

for i in range(M):
  x,y = (int(val) for val in input().split())
  a.append(x)
  b.append(y)

cnt=0
for j in range(M):
    
    val_a=a.popleft()
    val_b=b.popleft()

    stack=deque([1])
    visited=deque()

    while len(stack) > 0:
        val=stack.pop()
        if visited.count(val)==0:
            visited.append(val)
        for i in range(len(a)):
            if a[i]==val:
                if b[i] != visited:
                    stack.append(b[i])
        for i in range(len(b)):
            if b[i]==val:
                if a[i] != visited:
                    stack.append(a[i]) 
                        
    if len(visited) < N:
        cnt+=1
    
    a.append(val_a)
    b.append(val_b)

print(cnt)


# Fixed code:
import sys
input = sys.stdin.readline
from collections import deque

N,M=[int(val) for val in input().split()]
a=deque()
b=deque()

for i in range(M):
  x,y = (int(val) for val in input().split())
  a.append(x)
  b.append(y)

cnt=0
for j in range(M):
    
    val_a=a.popleft()
    val_b=b.popleft()

    stack=deque([1])
    visited=deque()

    while len(stack) > 0:
        val=stack.pop()
        if visited.count(val)==0:
            visited.append(val)
            for i in range(len(a)):
                if a[i]==val:
                    if b[i] != visited:
                        stack.append(b[i])
            for i in range(len(b)):
                if b[i]==val:
                    if a[i] != visited:
                        stack.append(a[i]) 
                        
    if len(visited) < N:
        cnt+=1
    
    a.append(val_a)
    b.append(val_b)

print(cnt)
# Buggy code:
N , M = map(int,input().split())

dotlist = [[] for i in range(N)]
sidlist = []
count = 0 

for m in range(M):
    a,b = map(int,input().split())
    dotlist[a -1].append(b)
    dotlist[b -1].append(a)
    sidlist.append([a,b])

if N -1 == M:
    print(0)
    exit()

def check(anum,bnum,cnum):
    for i in dotlist[cnum - 1]: 
        if (anum == cnum and i == bnum) or (bnum == cnum and i == anum):
            pass
        elif donedot[i - 1] == False:
            donedot[i - 1] = True
            print(cnum,i)
            check(anum,bnum,i)

donedot = None

for m in range(M):
    donedot = [False for i in range(M)]
    a,b = sidlist[m]
    check(a,b,1)
    TorF = True
    for i in donedot:
        TorF  = TorF and i
    if  not TorF:
        count += 1

print(count)


# Fixed code:
N , M = map(int,input().split())

dotlist = [[] for i in range(N)]
sidlist = []
count = 0 

for m in range(M):
    a,b = map(int,input().split())
    dotlist[a -1].append(b)
    dotlist[b -1].append(a)
    sidlist.append([a,b])

def check(anum,bnum,cnum):
    donedot[cnum-1] = True
    for i in dotlist[cnum - 1]: 
        if (anum == cnum and i == bnum) or (bnum == cnum and i == anum):
            pass
        elif donedot[i - 1] == False:
            check(anum,bnum,i)

donedot = None

for m in range(M):
    donedot = [False for i in range(N)]
    a,b = sidlist[m]
    check(a,b,1)
    TorF = True
    for i in donedot:
        TorF  = TorF and i
    if  not TorF:
        count += 1

print(count)
# Buggy code:
#coding: utf-8
import math
import heapq
import bisect
import numpy as np
from collections import Counter
#from scipy.misc import comb

N,M = map(int, input().split())
G = [[] for _ in range(N)]

E = []
for _ in range(M):
    a,b = map(int, input().split())
    G[a-1].append(b-1)
    G[b-1].append(a-1)
    E.append((a-1,b-1))

d = [0] + [-1]*(N-1)

def dfs(n):
    for v in G[n]:
        if d[v] == -1:
            dfs(v)

ans = 0
for a,b in E:
    G[a].remove(b)
    G[b].remove(a)

    dfs(0)

    if -1 in d:
        ans += 1
    
    for i in range(1,N):
        d[i] = -1

print(ans)

# Fixed code:
#coding: utf-8
import math
import heapq
import bisect
import numpy as np
from collections import Counter
#from scipy.misc import comb

N,M = map(int, input().split())
G = [[] for _ in range(N)]

E = []
for _ in range(M):
    a,b = map(int, input().split())
    G[a-1].append(b-1)
    G[b-1].append(a-1)
    E.append((a-1,b-1))

d = [0] + [-1]*(N-1)

def dfs(n):
    d[n] = 0
    for v in G[n]:
        if d[v] == -1:
            dfs(v)

ans = 0
for a,b in E:
    G[a].remove(b)
    G[b].remove(a)

    dfs(0)

    if -1 in d:
        ans += 1
    
    for i in range(1,N):
        d[i] = -1
    G[a].append(b)
    G[b].append(a)

print(ans)
# Buggy code:
N,M = map(int,input().split())

road = [[] for _ in range(N)]

for _ in range(M):
  a,b = map(int,input().split())
  road[a-1].append(b-1)
  road[b-1].append(a-1)

def dfs(v,w):
  l = [0 for _ in range(N)]
  l[v] = 1
  stack = [v]
  while stack:
    vv = stack.pop()
    for i in road[vv]:
      if i == w and v == vv or i == vv and v == w:
        continue
      else:
        if l[i] == 0:
          l[i] = 1
          stack.append(i)
  return sum(l)

ans = 0
check = [[0 for _ in range(N)] for _ in range(N)]

for n in range(N):
  for m in range(len(road[n])):
    if check[n][road[n][m]] == 0 or check[road[n][m]][n] == 0:
      check[n][road[n][m]] = 1
      check[road[n][m]][n] = 1
      d = dfs(n,road[n][m])
      if d != N:
        ans += 1

print(ans,road)

# Fixed code:
N,M = map(int,input().split())

road = [[] for _ in range(N)]

for _ in range(M):
  a,b = map(int,input().split())
  road[a-1].append(b-1)
  road[b-1].append(a-1)

def dfs(v,w):
  l = [0 for _ in range(N)]
  l[v] = 1
  stack = [v]
  while stack:
    vv = stack.pop()
    for i in road[vv]:
      if i == w and v == vv or i == vv and v == w:
        continue
      else:
        if l[i] == 0:
          l[i] = 1
          stack.append(i)
  return sum(l)

ans = 0
check = [[0 for _ in range(N)] for _ in range(N)]

for n in range(N):
  for m in range(len(road[n])):
    if check[n][road[n][m]] == 0 or check[road[n][m]][n] == 0:
      check[n][road[n][m]] = 1
      check[road[n][m]][n] = 1
      d = dfs(n,road[n][m])
      if d != N:
        ans += 1

print(ans)
# Buggy code:
from collections import deque
from copy import deepcopy

N,M = map(int,input().split())
Matrix = [[False for x in range(N)] for j in range(N)]

Path = []
for i in range(M) :
    a,b = map(int,input().split())
    a -= 1
    b -= 1
    Path.append((a,b))
    Matrix[a][b] = True
    Matrix[b][a] = True

INF = 63
ans = 0
for i in range(M) :
    Matrix_duplicated = deepcopy(Matrix)
    a,b = Path[i]
    Matrix_duplicated[a][b] = False
    Matrix_duplicated[b][a] = False
    Distance = [INF for i in range(N)]
    Distance[0] = 0
    Queue = deque([0])
    while Queue :
        now = Queue.popleft()
        Visited.append(now)
        for i in range(N) :
            if Matrix_duplicated[now][i] :
                Matrix_duplicated[now][i] = False
                Matrix_duplicated[i][now] = False
                Distance[i] = min(Distance[now]+1, Distance[i])
                Queue.append(i)
    if INF in Distance :
        ans += 1
print(ans)


# Fixed code:
from collections import deque
from copy import deepcopy

N,M = map(int,input().split())
Matrix = [[False for x in range(N)] for y in range(N)]

Path = []
for i in range(M) :
    a,b = map(int,input().split())
    a -= 1
    b -= 1
    Path.append((a,b))
    Matrix[a][b] = True
    Matrix[b][a] = True

INF = 63
ans = 0
for i in range(M) :
    Matrix_duplicated = deepcopy(Matrix)
    a,b = Path[i]
    Matrix_duplicated[a][b] = False
    Matrix_duplicated[b][a] = False
    Distance = [INF for i in range(N)]
    Distance[0] = 0
    Queue = deque([0])
    while Queue :
        now = Queue.popleft()
        for i in range(N) :
            if Matrix_duplicated[now][i] :
                Matrix_duplicated[now][i] = False
                Matrix_duplicated[i][now] = False
                Distance[i] = min(Distance[now]+1, Distance[i])
                Queue.append(i)
    if INF in Distance :
        ans += 1
print(ans)
# Buggy code:
n,m=map(int,input().split())
e=[list(map(int,input().split())) for _ in range(m)]

cnt=0
for x in e:
  l=list(range(n))
  for y in e:
    print('y',y)
    if y!=x:l=[l[y[0]-1] if l[i]==l[y[1]-1] else l[i] for i in range(n)]
    print('l',l)
  if len(set(l))!=1:cnt+=1
print(cnt)

# Fixed code:
n,m=map(int,input().split())
e=[list(map(int,input().split())) for _ in range(m)]

cnt=0
for x in e:
  l=list(range(n))
  for y in e:
    if y!=x:l=[l[y[0]-1] if l[i]==l[y[1]-1] else l[i] for i in range(n)]
  if len(set(l))!=1:cnt+=1
print(cnt)
# Buggy code:
def dfs(v):
    visited[v] = True
    for v2 in range(N):
        if graph[v][v2] == False:
            continue
        if visited[v2] == True:
            continue
        dfs(v2)

global N, M, graph, visited
N, M = [int(i) for i in input().split()]
graph = [[False for _ in range(50)] for _ in range(50)]
visited = [False for _ in range(50)] 
a = [0 for _ in range(50)]
b = [0 for _ in range(50)]
for i in range(N):
    a[i], b[i] = [int(i) for i in input().split()]
    a[i] -= 1
    b[i] -= 1
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = True
    
ans = 0
for i in range(M):
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = False
    for j in range(N):
        visited[j] = False
    dfs(0)

    bridge = False
    for j in range(N):
        if visited[j] == False:
            bridge = True
    if bridge:
        ans += 1
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = True
print(ans)


# Fixed code:
def dfs(v):
    visited[v] = True
    for v2 in range(N):
        if graph[v][v2] == False:
            continue
        if visited[v2] == True:
            continue
        dfs(v2)

global N, M, graph, visited
N, M = [int(i) for i in input().split()]
graph = [[False for _ in range(50)] for _ in range(50)]
visited = [False for _ in range(50)] 
a = [0 for _ in range(50)]
b = [0 for _ in range(50)]
for i in range(M):
    a[i], b[i] = [int(i) for i in input().split()]
    a[i] -= 1
    b[i] -= 1
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = True
    
ans = 0
for i in range(M):
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = False
    for j in range(N):
        visited[j] = False
    dfs(0)

    bridge = False
    for j in range(N):
        if visited[j] == False:
            bridge = True
    if bridge:
        ans += 1
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = True
print(ans)
# Buggy code:
def dfs(num):
  global visited
  for next_num in num:
    if visited[next_num]:
      continue
    if has_edge[num][next_num]:
      visited[next_num]=1
      dfs(next_num)
      
N,M = map(int,input().split())
ab = []
edge = [[] for x in range(N+1)]
has_edge = [[0 for x in range(N+1)] for x in range(N+1)]
for i in range(M):
  a,b = map(int,input().split())
  ab.append([a,b])
  edge[a].append(b)
  edge[b].append(a)
  has_edge[a][b] = 1
  has_edge[b][a] = 1
  
count = 0
for a,b in ab:
  visited = [0 for x in range(N+1)]
  visited[1] = 1
  has_edge[a][b] = 0
  has_edge[b][a] = 0
  dfs(1)
  if sum(visited) != N:
    count += 1
  has_edge[a][b] = 1
  has_edge[b][a] = 1
print(count)

# Fixed code:
def dfs(num):
  global visited
  for next_num in edge[num]:
    if visited[next_num]:
      continue
    if has_edge[num][next_num]:
      visited[next_num]=1
      dfs(next_num)
      
N,M = map(int,input().split())
ab = []
edge = [[] for x in range(N+1)]
has_edge = [[0 for x in range(N+1)] for x in range(N+1)]
for i in range(M):
  a,b = map(int,input().split())
  ab.append([a,b])
  edge[a].append(b)
  edge[b].append(a)
  has_edge[a][b] = 1
  has_edge[b][a] = 1
  
count = 0
for a,b in ab:
  visited = [0 for x in range(N+1)]
  visited[1] = 1
  has_edge[a][b] = 0
  has_edge[b][a] = 0
  dfs(1)
  if sum(visited) != N:
    count += 1
  has_edge[a][b] = 1
  has_edge[b][a] = 1
print(count)
# Buggy code:
n,m = map(int,input().split())
data = []
G = [[] for i in range(n)]
for i in range(m):
    a,b = map(int,input().split())
    data.append((a-1,b-1))
    G[a].append(b)
    G[b].append(a)

def dfs(v,seen):
    if seen[v]: return
    seen[v] = True
    for nv in G[v]:
        dfs(nv,seen)

cnt = 0

for i in range(m):
    ra,rb = data[i]
    G[ra].remove(rb)
    G[rb].remove(ra)
    seen = [False]*n
    cnt += (sum(seen) == n)
    G[a].append(b)
    G[b].append(a)

print(cnt)

# Fixed code:
n,m = map(int,input().split())
data = []
G = [[] for i in range(n)]
for i in range(m):
    a,b = map(int,input().split())
    data.append((a-1,b-1))
    G[a-1].append(b-1)
    G[b-1].append(a-1)

def dfs(v,seen):
    if seen[v]: return
    seen[v] = True
    for nv in G[v]:
        dfs(nv,seen)

cnt = 0

for i in range(m):
    ra,rb = data[i]
    G[ra].remove(rb)
    G[rb].remove(ra)
    seen = [False]*n
    dfs(0,seen)
    cnt += (sum(seen) != n)
    G[ra].append(rb)
    G[rb].append(ra)

print(cnt)
# Buggy code:
from collections import deque
n,m = map(int,input().split())
L = [[] for _ in range(n)]

for i in range(m):
    a,b = map(int,input().split())
    a,b = a-1,b-1
    L[a].append(b)
    L[b].append(a)
#print(L)
cnt = 0

for i in range(m):
    G = [[] for _ in range(n)]
    visited = [0]*n
    for j in range(m):
        if i == j:
            continue
    Q = deque([0])
    while Q:
        q = Q.pop()
        for g in G[q]:
            if visited[g] == 0:
                visited[g] = 1
                #print(visited)
                Q.append(g)
    if 0 in visited:
        cnt +=1
print(cnt)

# Fixed code:
from collections import deque
n,m = map(int,input().split())
L =[list(map(int, input().split())) for _ in range(m)]
#print(L)
cnt = 0
for i in range(m):
    G = [[] for _ in range(n)]
    
    for j in range(m):
        if i == j:
            continue
        a,b = L[j][0],L[j][1]
        #print(a-1,b-1)
        G[a-1].append(b-1)
        G[b-1].append(a-1)
    #print(G)
    Q = deque()
    Q.append(0)
    visited = [0]*n
    visited[0] = 1
    while Q:
        q = Q.pop()
        for g in G[q]:
            if visited[g] == 0:
                visited[g] = 1
                #print(visited)
                Q.append(g)

    if 0 in visited:
        cnt +=1
print(cnt)
# Buggy code:
f = lambda: list(map(int,input().split()))
f_ = lambda: [int(x)-1 for x in input().split()]


class UnionFind(object):
    def __init__(self, size):
        self.parent = [i for i in range(size)]
        self.rank = [0 for _ in range(size)]

    def find(self, x):
        if self.parent[x] == x:
            return x
        else:
            return self.find(self.parent[x])

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return

        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)


n,m = f()
u = UnionFind(n)
e = []
for _ in range(m):
    e.append(f_())

ans = 0
for edge in e:
    e.remove(edge)
    for a,b in e:
        u.unite(a,b)

    f = False
    k = u.find(0)
    for i in range(n):
        if u.find(i) is not k:
            f = True
            break
    if f:
        ans += 1
print(ans)


# Fixed code:
f = lambda: list(map(int,input().split()))
f_ = lambda: [int(x)-1 for x in input().split()]


class UnionFind(object):
    def __init__(self, size):
        self.parent = [i for i in range(size)]
        self.rank = [0 for _ in range(size)]

    def find(self, x):
        if self.parent[x] == x:
            return x
        else:
            return self.find(self.parent[x])

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return

        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)


n,m = f()
E = []
for _ in range(m):
    E.append(f_())

ans = 0
for edge in E:
    e = [i for i in E if not i == edge]
    u = UnionFind(n)
    for a,b in e:
        u.unite(a,b)

    f = False
    k = u.find(0)
    for i in range(n):
        if u.find(i) is not k:
            f = True
            break
    if f:
        ans += 1
print(ans)