from collections import deque



n,m = list(map(int,input().split()))

G = [[0]*n for _ in range(n)]

E = []

for i in range(m):

    a,b = list(map(int,input().split()))

    a,b = a-1, b-1

    G[a][b] = 1

    G[b][a] = 1

    E.append((a,b))



ans = 0

for e in E:

    del_a, del_b = e

    

    #対象の辺を消す

    G[del_a][del_b] = 0

    G[del_b][del_a] = 0

    

    que = ([0])

    visited = [False]*n

    while que:

        node = que.pop()

        if visited[node] == True:

            continue

        visited[node] = True

        for j in range(n):

            if G[node][j] == 1:

                que.append(j)

    if False in visited:

        ans += 1

    

    #対象の辺を戻す

    G[del_a][del_b] = 1

    G[del_b][del_a] = 1

print(ans)
class UnionFind:

    #要素数nで初期化

    #インスタンス変数の初期化

    def __init__(self, n):

        #root : 木の要素数

        #rnk : 木の高さ(rank)

        self.n = n

        self.root = [-1]*(n+1)

        self.rnk = [0]*(n+1)

    

    """ノードxのrootノードを見つける"""

    def Find_Root(self, x):

        if self.root[x] < 0:

            return x

        else:

            self.root[x] = self.Find_Root(self.root[x]) 

            return self.root[x]

    

    """木の合併"""

    def Union(self, x, y):

        #入力ノードの親を探索

        x = self.Find_Root(x)

        y = self.Find_Root(y)

        

        #既に同じ木に所属する場合

        if (x==y):

            return 

        

        #異なる木に所属する場合 -> rnkから判断して合併する

        elif (self.rnk[x] > self.rnk[y]):

            self.root[x] += self.root[y]

            self.root[y] = x

        

        else:

            self.root[y] += self.root[x]

            self.root[x] = y

            

            #rnkが同じ(深さが同じ)場合

            if self.rnk[x]==self.rnk[y]:

                self.rnk[y] += 1

    

    """xとyが同じグループに所属するか"""

    def isSameGroup(self, x, y):

        return self.Find_Root(x) == self.Find_Root(y)

    

    """ノードxが属する木のサイズ"""

    def Count(self, x):

        return -self.root[self.Find_Root(x)]





n,m = list(map(int,input().split()))

edge = []

for i in range(m):

    a,b = list(map(int,input().split()))

    edge.append([a,b])



res = 0

for i in range(m):

    tmp_edge = edge[:i] + edge[i+1:]

    uf = UnionFind(n)

    for j in range(len(tmp_edge)):

        uf.Union(tmp_edge[j][0], tmp_edge[j][1])

    if not uf.isSameGroup(edge[i][0], edge[i][1]):

        res += 1

print(res)
from collections import deque

n, m = list(map(int, input().split()))
G = [[0] * n for _ in range(n)]
E = []
for i in range(m):
    a, b = list(map(int, input().split()))
    a, b = a - 1, b - 1
    G[a][b] = 1
    G[b][a] = 1
    E.append((a, b))
ans = 0
for e in E:
    del_a, del_b = e
    # 対象の辺を消す
    G[del_a][del_b] = 0
    G[del_b][del_a] = 0
    que = [0]
    visited = [False] * n
    while que:
        node = que.pop()
        if visited[node] == True:
            continue
        visited[node] = True
        for j in range(n):
            if G[node][j] == 1:
                que.append(j)
    if False in visited:
        ans += 1
    # 対象の辺を戻す
    G[del_a][del_b] = 1
    G[del_b][del_a] = 1
print(ans)

class UnionFind:
    # 要素数nで初期化
    # インスタンス変数の初期化
    def __init__(self, n):
        # root : 木の要素数
        # rnk : 木の高さ(rank)
        self.n = n
        self.root = [-1] * (n + 1)
        self.rnk = [0] * (n + 1)

    """ノードxのrootノードを見つける"""

    def Find_Root(self, x):
        if self.root[x] < 0:
            return x
        else:
            self.root[x] = self.Find_Root(self.root[x])
            return self.root[x]

    """木の合併"""

    def Union(self, x, y):
        # 入力ノードの親を探索
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        # 既に同じ木に所属する場合
        if x == y:
            return
        # 異なる木に所属する場合 -> rnkから判断して合併する
        elif self.rnk[x] > self.rnk[y]:
            self.root[x] += self.root[y]
            self.root[y] = x
        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            # rnkが同じ(深さが同じ)場合
            if self.rnk[x] == self.rnk[y]:
                self.rnk[y] += 1

    """xとyが同じグループに所属するか"""

    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    """ノードxが属する木のサイズ"""

    def Count(self, x):
        return -self.root[self.Find_Root(x)]


n, m = list(map(int, input().split()))
edge = []
for i in range(m):
    a, b = list(map(int, input().split()))
    edge.append([a, b])
res = 0
for i in range(m):
    tmp_edge = edge[:i] + edge[i + 1 :]
    uf = UnionFind(n)
    for j in range(len(tmp_edge)):
        uf.Union(tmp_edge[j][0], tmp_edge[j][1])
    if not uf.isSameGroup(edge[i][0], edge[i][1]):
        res += 1
print(res)

-from collections import deque +class UnionFind: +    # 要素数nで初期化 +    # インスタンス変数の初期化 +    def __init__(self, n): +        # root : 木の要素数 +        # rnk : 木の高さ(rank) +        self.n = n +        self.root = [-1] * (n + 1) +        self.rnk = [0] * (n + 1) + +    """ノードxのrootノードを見つける""" + +    def Find_Root(self, x): +        if self.root[x] < 0: +            return x +        else: +            self.root[x] = self.Find_Root(self.root[x]) +            return self.root[x] + +    """木の合併""" + +    def Union(self, x, y): +        # 入力ノードの親を探索 +        x = self.Find_Root(x) +        y = self.Find_Root(y) +        # 既に同じ木に所属する場合 +        if x == y: +            return +        # 異なる木に所属する場合 -> rnkから判断して合併する +        elif self.rnk[x] > self.rnk[y]: +            self.root[x] += self.root[y] +            self.root[y] = x +        else: +            self.root[y] += self.root[x] +            self.root[x] = y +            # rnkが同じ(深さが同じ)場合 +            if self.rnk[x] == self.rnk[y]: +                self.rnk[y] += 1 + +    """xとyが同じグループに所属するか""" + +    def isSameGroup(self, x, y): +        return self.Find_Root(x) == self.Find_Root(y) + +    """ノードxが属する木のサイズ""" + +    def Count(self, x): +        return -self.root[self.Find_Root(x)] + -G = [[0] * n for _ in range(n)] -E = [] +edge = [] -    a, b = a - 1, b - 1 -    G[a][b] = 1 -    G[b][a] = 1 -    E.append((a, b)) -ans = 0 -for e in E: -    del_a, del_b = e -    # 対象の辺を消す -    G[del_a][del_b] = 0 -    G[del_b][del_a] = 0 -    que = [0] -    visited = [False] * n -    while que: -        node = que.pop() -        if visited[node] == True: -            continue -        visited[node] = True -        for j in range(n): -            if G[node][j] == 1: -                que.append(j) -    if False in visited: -        ans += 1 -    # 対象の辺を戻す -    G[del_a][del_b] = 1 -    G[del_b][del_a] = 1 -print(ans) +    edge.append([a, b]) +res = 0 +for i in range(m): +    tmp_edge = edge[:i] + edge[i + 1 :] +    uf = UnionFind(n) +    for j in range(len(tmp_edge)): +        uf.Union(tmp_edge[j][0], tmp_edge[j][1]) +    if not uf.isSameGroup(edge[i][0], edge[i][1]): +        res += 1 +print(res)