from sys import setrecursionlimit

#setrecursionlimit(10**5)

class UnionFind:

    def __init__(self, n):

        # 親要素のノード番号を格納

        # par[x]=xの時そのノードは根　

        self.par = [i for i in range(n + 1)]

        # rank

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

        self.size = [1] * (n + 1)



    def find(self, x):

        # 根の番号を返す(所属する集合を確認する)

        if self.par[x] == x:

            return x

        else:

            self.par[x] = self.find(self.par[x])

            return self.par[x]



    def check(self, x, y):

        # x,yが同じ集合に属するかどうか調べる

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





    def union(self, x, y):

        # 根を探す

        x = self.find(x)

        y = self.find(y)

        if x == y:return

        # rankの小さいものを大きいほうにくっつける

        if self.rank[x] < self.rank[y]:

            self.par[x] = y

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

        else:

            self.par[y] = x

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

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

                self.rank[x] += 1



    def count_group(self, n):

        return len({self.find(x) for x in range(1, n + 1)})



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

ab = [list(map(int,input().split())) for i in range(m)]



cnt = 0

for i in range(m):

    uf = UnionFind(n)

    for j in range(m):

        if i == j:continue

        a, b = ab[j]

        uf.union(a, b)



    if uf.count_group(n) != 1:cnt += 1

print(cnt)
#グラフの連結成分を調べる

def Graph(ab):

    G=[[] for i in range(n)]

    for a,b in ab:

        G[a-1].append(b)

        G[b-1].append(a)

    return G



from collections import deque

def dfs(G, a, b):

    #(a, b)は除外する辺

    q=deque()

    q.append((1, -1, 0))

    log = [0] * n

    log[0] = 1

    while q:

        V,P,S=q.pop()

        if S==0:

            #下に遷移していくときの処理

            #q.append((V,P,1))

            for new_v in G[V-1]:

                if {a, b} == {new_v, V}:continue

                if new_v==P:continue

                if log[new_v - 1]:continue

                log[new_v - 1] = 1

                q.append((new_v,V,0))



    return sum(log) != n



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

ab = [list(map(int,input().split())) for i in range(m)]

G = Graph(ab)

'''

ab一個を除いた時に連結かどうか調べる

'''



ans = 0

for a, b in ab:

    if dfs(G, a, b):ans += 1

print(ans)
from sys import setrecursionlimit

# setrecursionlimit(10**5)
class UnionFind:
    def __init__(self, n):
        # 親要素のノード番号を格納
        # par[x]=xの時そのノードは根
        self.par = [i for i in range(n + 1)]
        # rank
        self.rank = [0] * (n + 1)
        self.size = [1] * (n + 1)

    def find(self, x):
        # 根の番号を返す(所属する集合を確認する)
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def check(self, x, y):
        # x,yが同じ集合に属するかどうか調べる
        return self.find(x) == self.find(y)

    def union(self, x, y):
        # 根を探す
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        # rankの小さいものを大きいほうにくっつける
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    def count_group(self, n):
        return len({self.find(x) for x in range(1, n + 1)})


n, m = list(map(int, input().split()))
ab = [list(map(int, input().split())) for i in range(m)]
cnt = 0
for i in range(m):
    uf = UnionFind(n)
    for j in range(m):
        if i == j:
            continue
        a, b = ab[j]
        uf.union(a, b)
    if uf.count_group(n) != 1:
        cnt += 1
print(cnt)

# グラフの連結成分を調べる
def Graph(ab):
    G = [[] for i in range(n)]
    for a, b in ab:
        G[a - 1].append(b)
        G[b - 1].append(a)
    return G


from collections import deque


def dfs(G, a, b):
    # (a, b)は除外する辺
    q = deque()
    q.append((1, -1, 0))
    log = [0] * n
    log[0] = 1
    while q:
        V, P, S = q.pop()
        if S == 0:
            # 下に遷移していくときの処理
            # q.append((V,P,1))
            for new_v in G[V - 1]:
                if {a, b} == {new_v, V}:
                    continue
                if new_v == P:
                    continue
                if log[new_v - 1]:
                    continue
                log[new_v - 1] = 1
                q.append((new_v, V, 0))
    return sum(log) != n


n, m = list(map(int, input().split()))
ab = [list(map(int, input().split())) for i in range(m)]
G = Graph(ab)
"""
ab一個を除いた時に連結かどうか調べる
"""
ans = 0
for a, b in ab:
    if dfs(G, a, b):
        ans += 1
print(ans)

-from sys import setrecursionlimit +# グラフの連結成分を調べる +def Graph(ab): +    G = [[] for i in range(n)] +    for a, b in ab: +        G[a - 1].append(b) +        G[b - 1].append(a) +    return G -# setrecursionlimit(10**5) -class UnionFind: -    def __init__(self, n): -        # 親要素のノード番号を格納 -        # par[x]=xの時そのノードは根 -        self.par = [i for i in range(n + 1)] -        # rank -        self.rank = [0] * (n + 1) -        self.size = [1] * (n + 1) -    def find(self, x): -        # 根の番号を返す(所属する集合を確認する) -        if self.par[x] == x: -            return x -        else: -            self.par[x] = self.find(self.par[x]) -            return self.par[x] +from collections import deque -    def check(self, x, y): -        # x,yが同じ集合に属するかどうか調べる -        return self.find(x) == self.find(y) -    def union(self, x, y): -        # 根を探す -        x = self.find(x) -        y = self.find(y) -        if x == y: -            return -        # rankの小さいものを大きいほうにくっつける -        if self.rank[x] < self.rank[y]: -            self.par[x] = y -            self.size[y] += self.size[x] -        else: -            self.par[y] = x -            self.size[x] += self.size[y] -            if self.rank[x] == self.rank[y]: -                self.rank[x] += 1 - -    def count_group(self, n): -        return len({self.find(x) for x in range(1, n + 1)}) +def dfs(G, a, b): +    # (a, b)は除外する辺 +    q = deque() +    q.append((1, -1, 0)) +    log = [0] * n +    log[0] = 1 +    while q: +        V, P, S = q.pop() +        if S == 0: +            # 下に遷移していくときの処理 +            # q.append((V,P,1)) +            for new_v in G[V - 1]: +                if {a, b} == {new_v, V}: +                    continue +                if new_v == P: +                    continue +                if log[new_v - 1]: +                    continue +                log[new_v - 1] = 1 +                q.append((new_v, V, 0)) +    return sum(log) != n -cnt = 0 -for i in range(m): -    uf = UnionFind(n) -    for j in range(m): -        if i == j: -            continue -        a, b = ab[j] -        uf.union(a, b) -    if uf.count_group(n) != 1: -        cnt += 1 -print(cnt) +G = Graph(ab) +""" +ab一個を除いた時に連結かどうか調べる +""" +ans = 0 +for a, b in ab: +    if dfs(G, a, b): +        ans += 1 +print(ans)