class uf_tree:

    def __init__(self, n):

        self.sizes = [0] * n

        self.par = list(range(n))



    def find(self, x):

        if x == self.par[x]:

            return x

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

        return self.par[x]



    def unite(self, x, y):

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

        if x == y:

            return

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

            x, y = y, x

        self.par[y] = x

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



    def same(self, x, y):

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





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()))

    a[i] -= 1; b[i] -= 1

ans = 0

for i in range(M):

    uf = uf_tree(N+1)

    for j in range(M):

        if i == j:

            continue

        uf.unite(a[j], b[j])



    bridge = False

    for i in range(N):

        if not uf.same(0, i):

            bridge = True

    if bridge:

        ans += 1



print(ans)

#!/usr/bin/env python3



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

edges = []

graph = [ [] for _ in range(n) ]



for i in range(m):

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

    a -= 1; b -= 1;

    edges.append( (a, b) )



    graph[a].append(b)

    graph[b].append(a)



def dfs(u, v):

    is_visited = [ False ]*n

    st = []

    st.append(0)

    while st:

        cur = st.pop()

        is_visited[cur] = True

        for adj in graph[cur]:

            if is_visited[adj]: continue

            if cur == u and adj == v: continue

            if cur == v and adj == u: continue



            st.append(adj)



    return all(is_visited)



ans = 0

for u, v in edges:

    if not dfs(u, v):

        ans += 1



print(ans)



class uf_tree:
    def __init__(self, n):
        self.sizes = [0] * n
        self.par = list(range(n))

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

    def unite(self, x, y):
        x, y = self.find(x), self.find(y)
        if x == y:
            return
        if self.sizes[x] < self.sizes[y]:
            x, y = y, x
        self.par[y] = x
        self.sizes[x] += self.sizes[y]

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


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()))
    a[i] -= 1
    b[i] -= 1
ans = 0
for i in range(M):
    uf = uf_tree(N + 1)
    for j in range(M):
        if i == j:
            continue
        uf.unite(a[j], b[j])
    bridge = False
    for i in range(N):
        if not uf.same(0, i):
            bridge = True
    if bridge:
        ans += 1
print(ans)

#!/usr/bin/env python3
n, m = list(map(int, input().split()))
edges = []
graph = [[] for _ in range(n)]
for i in range(m):
    a, b = list(map(int, input().split()))
    a -= 1
    b -= 1
    edges.append((a, b))
    graph[a].append(b)
    graph[b].append(a)


def dfs(u, v):
    is_visited = [False] * n
    st = []
    st.append(0)
    while st:
        cur = st.pop()
        is_visited[cur] = True
        for adj in graph[cur]:
            if is_visited[adj]:
                continue
            if cur == u and adj == v:
                continue
            if cur == v and adj == u:
                continue
            st.append(adj)
    return all(is_visited)


ans = 0
for u, v in edges:
    if not dfs(u, v):
        ans += 1
print(ans)

-class uf_tree: -    def __init__(self, n): -        self.sizes = [0] * n -        self.par = list(range(n)) - -    def find(self, x): -        if x == self.par[x]: -            return x -        self.par[x] = self.find(self.par[x]) -        return self.par[x] - -    def unite(self, x, y): -        x, y = self.find(x), self.find(y) -        if x == y: -            return -        if self.sizes[x] < self.sizes[y]: -            x, y = y, x -        self.par[y] = x -        self.sizes[x] += self.sizes[y] - -    def same(self, x, y): -        return self.find(x) == self.find(y) +#!/usr/bin/env python3 +n, m = list(map(int, input().split())) +edges = [] +graph = [[] for _ in range(n)] +for i in range(m): +    a, b = list(map(int, input().split())) +    a -= 1 +    b -= 1 +    edges.append((a, b)) +    graph[a].append(b) +    graph[b].append(a) -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())) -    a[i] -= 1 -    b[i] -= 1 +def dfs(u, v): +    is_visited = [False] * n +    st = [] +    st.append(0) +    while st: +        cur = st.pop() +        is_visited[cur] = True +        for adj in graph[cur]: +            if is_visited[adj]: +                continue +            if cur == u and adj == v: +                continue +            if cur == v and adj == u: +                continue +            st.append(adj) +    return all(is_visited) + + -for i in range(M): -    uf = uf_tree(N + 1) -    for j in range(M): -        if i == j: -            continue -        uf.unite(a[j], b[j]) -    bridge = False -    for i in range(N): -        if not uf.same(0, i): -            bridge = True -    if bridge: +for u, v in edges: +    if not dfs(u, v):