from queue import Queue

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

a, b = [0] * M, [0] * M

g = [[False] * N for _ in range(N)]

for i in range(M):

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

    g[a[i]-1][b[i]-1] = True

    g[b[i]-1][a[i]-1] = True



ans = 0

for _a, _b in zip(a, b):

    g[_a-1][_b-1] = False

    g[_b-1][_a-1] = False

    visit = [False] * N

    q = Queue()

    q.put(0)

    while not q.empty():

        v = q.get()

        visit[v] = True

        for adj_v, adj in enumerate(g[v]):

            if not adj or visit[adj_v]:

                continue

            q.put(adj_v)

    if not all(visit):

        ans += 1

    g[_a-1][_b-1] = True

    g[_b-1][_a-1] = True

print(ans)
class UnionFind(object):

    def __init__(self, n):

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

        self.rank = [0 for _ in range(n)]

        self._size = n



    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 union(self, x, y):

        x = self.find(x)

        y = self.find(y)

        if x != y:

            self._size -= 1

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

                x, y = y, x

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

                self.rank[x] += 1

            self.par[y] = x



    def is_same(self, x, y):

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



    def size(self):

        return self._size



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

a, b = [0] * M, [0] * M

for i in range(M):

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



ans = 0

for i in range(M):

    uf = UnionFind(n=N)

    for j in range(M):

        if j == i:

            continue

        uf.union(a[j]-1, b[j]-1)

    if uf.size() != 1:

        ans += 1

print(ans)
from queue import Queue

N, M = list(map(int, input().split()))
a, b = [0] * M, [0] * M
g = [[False] * N for _ in range(N)]
for i in range(M):
    a[i], b[i] = list(map(int, input().split()))
    g[a[i] - 1][b[i] - 1] = True
    g[b[i] - 1][a[i] - 1] = True
ans = 0
for _a, _b in zip(a, b):
    g[_a - 1][_b - 1] = False
    g[_b - 1][_a - 1] = False
    visit = [False] * N
    q = Queue()
    q.put(0)
    while not q.empty():
        v = q.get()
        visit[v] = True
        for adj_v, adj in enumerate(g[v]):
            if not adj or visit[adj_v]:
                continue
            q.put(adj_v)
    if not all(visit):
        ans += 1
    g[_a - 1][_b - 1] = True
    g[_b - 1][_a - 1] = True
print(ans)

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

    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 union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x != y:
            self._size -= 1
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.par[y] = x

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

    def size(self):
        return self._size


N, M = list(map(int, input().split()))
a, b = [0] * M, [0] * M
for i in range(M):
    a[i], b[i] = list(map(int, input().split()))
ans = 0
for i in range(M):
    uf = UnionFind(n=N)
    for j in range(M):
        if j == i:
            continue
        uf.union(a[j] - 1, b[j] - 1)
    if uf.size() != 1:
        ans += 1
print(ans)

-from queue import Queue +class UnionFind(object): +    def __init__(self, n): +        self.par = [i for i in range(n)] +        self.rank = [0 for _ in range(n)] +        self._size = n + +    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 union(self, x, y): +        x = self.find(x) +        y = self.find(y) +        if x != y: +            self._size -= 1 +            if self.rank[x] < self.rank[y]: +                x, y = y, x +            if self.rank[x] == self.rank[y]: +                self.rank[x] += 1 +            self.par[y] = x + +    def is_same(self, x, y): +        return self.find(x) == self.find(y) + +    def size(self): +        return self._size + -g = [[False] * N for _ in range(N)] -    g[a[i] - 1][b[i] - 1] = True -    g[b[i] - 1][a[i] - 1] = True -for _a, _b in zip(a, b): -    g[_a - 1][_b - 1] = False -    g[_b - 1][_a - 1] = False -    visit = [False] * N -    q = Queue() -    q.put(0) -    while not q.empty(): -        v = q.get() -        visit[v] = True -        for adj_v, adj in enumerate(g[v]): -            if not adj or visit[adj_v]: -                continue -            q.put(adj_v) -    if not all(visit): +for i in range(M): +    uf = UnionFind(n=N) +    for j in range(M): +        if j == i: +            continue +        uf.union(a[j] - 1, b[j] - 1) +    if uf.size() != 1: -    g[_a - 1][_b - 1] = True -    g[_b - 1][_a - 1] = True