from collections import deque



N, M = list(map(int, input().split()))

edges = []



for _ in range(M):

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

    a -= 1

    b -= 1

    edges.append((a, b))



ans = 0

for removeEdge in range(M):

    confilm = [False for _ in range(N)]

    que = deque([])

    que.append(0)



    while que:

        now = que.popleft()

        confilm[now] = True

        for i, (a, b) in enumerate(edges):

            if i == removeEdge:

                continue

            if a == now:

                if not confilm[b]:

                    que.append(b)

            if b == now:

                if not confilm[a]:

                    que.append(a)

    if False in confilm:

        ans += 1



print(ans)


class UnionFind :

    def __init__(self, size) :

        self.parent = list(range(size))

        self.height = [0] * size

        self.size = [1] * size

        self.component = size



    def root(self, index) :

        if self.parent[index] == index :  # 根の場合

            return index

        rootIndex = self.root(self.parent[index])  # 葉の場合親の根を取得

        self.parent[index] = rootIndex  # 親の付け直し

        return rootIndex



    def union(self, index1, index2) :  # 結合

        root1 = self.root(index1)

        root2 = self.root(index2)



        if root1 == root2 :  # 連結されている場合

            return



        self.component -= 1  # 連結成分を減らす



        if self.height[root1] < self.height[root2] :

            self.parent[root1] = root2  # root2に結合

            self.size[root2] += self.size[root1]

        else :

            self.parent[root2] = root1  # root1に結合

            self.size[root1] += self.size[root2]

            if self.height[root1] == self.height[root2] :

                self.height[root1] += 1

        return



    def isSameRoot(self, index1, index2) :

        return self.root(index1) == self.root(index2)



    def sizeOfSameRoot(self, index) :

        return self.size[self.root(index)]



    def getComponent(self) :

        return self.component



N, M = list(map(int, input().split()))

AB = [tuple([int(a) - 1 for a in input().split()]) for _ in range(M)]



ans = 0

for i in range(M):

    tree = UnionFind(N)

    for a, b in (AB[:i] + AB[i + 1:]):

        tree.union(a, b)

    if tree.getComponent() > 1:

        ans += 1

print(ans)

from collections import deque

N, M = list(map(int, input().split()))
edges = []
for _ in range(M):
    a, b = list(map(int, input().split()))
    a -= 1
    b -= 1
    edges.append((a, b))
ans = 0
for removeEdge in range(M):
    confilm = [False for _ in range(N)]
    que = deque([])
    que.append(0)
    while que:
        now = que.popleft()
        confilm[now] = True
        for i, (a, b) in enumerate(edges):
            if i == removeEdge:
                continue
            if a == now:
                if not confilm[b]:
                    que.append(b)
            if b == now:
                if not confilm[a]:
                    que.append(a)
    if False in confilm:
        ans += 1
print(ans)

class UnionFind:
    def __init__(self, size):
        self.parent = list(range(size))
        self.height = [0] * size
        self.size = [1] * size
        self.component = size

    def root(self, index):
        if self.parent[index] == index:  # 根の場合
            return index
        rootIndex = self.root(self.parent[index])  # 葉の場合親の根を取得
        self.parent[index] = rootIndex  # 親の付け直し
        return rootIndex

    def union(self, index1, index2):  # 結合
        root1 = self.root(index1)
        root2 = self.root(index2)
        if root1 == root2:  # 連結されている場合
            return
        self.component -= 1  # 連結成分を減らす
        if self.height[root1] < self.height[root2]:
            self.parent[root1] = root2  # root2に結合
            self.size[root2] += self.size[root1]
        else:
            self.parent[root2] = root1  # root1に結合
            self.size[root1] += self.size[root2]
            if self.height[root1] == self.height[root2]:
                self.height[root1] += 1
        return

    def isSameRoot(self, index1, index2):
        return self.root(index1) == self.root(index2)

    def sizeOfSameRoot(self, index):
        return self.size[self.root(index)]

    def getComponent(self):
        return self.component


N, M = list(map(int, input().split()))
AB = [tuple([int(a) - 1 for a in input().split()]) for _ in range(M)]
ans = 0
for i in range(M):
    tree = UnionFind(N)
    for a, b in AB[:i] + AB[i + 1 :]:
        tree.union(a, b)
    if tree.getComponent() > 1:
        ans += 1
print(ans)

-from collections import deque +class UnionFind: +    def __init__(self, size): +        self.parent = list(range(size)) +        self.height = [0] * size +        self.size = [1] * size +        self.component = size + +    def root(self, index): +        if self.parent[index] == index:  # 根の場合 +            return index +        rootIndex = self.root(self.parent[index])  # 葉の場合親の根を取得 +        self.parent[index] = rootIndex  # 親の付け直し +        return rootIndex + +    def union(self, index1, index2):  # 結合 +        root1 = self.root(index1) +        root2 = self.root(index2) +        if root1 == root2:  # 連結されている場合 +            return +        self.component -= 1  # 連結成分を減らす +        if self.height[root1] < self.height[root2]: +            self.parent[root1] = root2  # root2に結合 +            self.size[root2] += self.size[root1] +        else: +            self.parent[root2] = root1  # root1に結合 +            self.size[root1] += self.size[root2] +            if self.height[root1] == self.height[root2]: +                self.height[root1] += 1 +        return + +    def isSameRoot(self, index1, index2): +        return self.root(index1) == self.root(index2) + +    def sizeOfSameRoot(self, index): +        return self.size[self.root(index)] + +    def getComponent(self): +        return self.component + -edges = [] -for _ in range(M): -    a, b = list(map(int, input().split())) -    a -= 1 -    b -= 1 -    edges.append((a, b)) +AB = [tuple([int(a) - 1 for a in input().split()]) for _ in range(M)] -for removeEdge in range(M): -    confilm = [False for _ in range(N)] -    que = deque([]) -    que.append(0) -    while que: -        now = que.popleft() -        confilm[now] = True -        for i, (a, b) in enumerate(edges): -            if i == removeEdge: -                continue -            if a == now: -                if not confilm[b]: -                    que.append(b) -            if b == now: -                if not confilm[a]: -                    que.append(a) -    if False in confilm: +for i in range(M): +    tree = UnionFind(N) +    for a, b in AB[:i] + AB[i + 1 :]: +        tree.union(a, b) +    if tree.getComponent() > 1: