def multival(): return list(map(int,input().split()))

def data(N=1): return [list(map(int,input().split())) for _ in range(N)]

mod = 10**9 + 7

inf = float("inf")





N,M = multival()

nemat = [[0]*N for _ in range(N)]

ans = M

info = []

for _ in range(M):

    a,b = multival()

    a -= 1; b-= 1

    nemat[a][b] = 1

    nemat[b][a] = 1

    info.append([a,b])



def dfs(now,visited):

    visited[now] = True

    if all(visited):

        global ans

        ans -= 1

        return

    for ne in range(N):

        if nemat[now][ne] == 1 and visited[ne] is False:

            dfs(ne,visited)

    

for i,j in info:

    nemat[i][j] = 0

    nemat[j][i] = 0

    dfs(0,[False]*N)

    nemat[i][j] = 1

    nemat[j][i] = 1



print(ans)
class Unionfind:



    __slots__ = ['nodes']



    def __init__(self, n):

        self.nodes = [-1]*n



    def root(self, x):

        if self.nodes[x] < 0:

            return x

        else:

            root_x = self.root(self.nodes[x])

            self.nodes[x] = root_x

            return root_x



    def unite(self, x, y):

        x = self.root(x); y = self.root(y)

        if x == y:

            return

        rank_x = -self.nodes[x]; rank_y = -self.nodes[y]

        if rank_x < rank_y:

            x, y = y, x

        if rank_x == rank_y:

            self.nodes[x] -= 1

        self.nodes[y] = x



    def same(self, x, y):

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



    def rank(self, x):

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



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

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



def bridge(k):

    uf = Unionfind(N)

    for i,pair in enumerate(info):

        if i == k: continue

        a = pair[0] - 1; b = pair[1] - 1

        uf.unite(a,b)

    s = {uf.root(i) for i in range(N)}

    if len(s) != 1:

        return True

    return False



cnt = 0

for k in range(M):

    if bridge(k):

        cnt += 1



print(cnt)
def multival():
    return list(map(int, input().split()))


def data(N=1):
    return [list(map(int, input().split())) for _ in range(N)]


mod = 10**9 + 7
inf = float("inf")
N, M = multival()
nemat = [[0] * N for _ in range(N)]
ans = M
info = []
for _ in range(M):
    a, b = multival()
    a -= 1
    b -= 1
    nemat[a][b] = 1
    nemat[b][a] = 1
    info.append([a, b])


def dfs(now, visited):
    visited[now] = True
    if all(visited):
        global ans
        ans -= 1
        return
    for ne in range(N):
        if nemat[now][ne] == 1 and visited[ne] is False:
            dfs(ne, visited)


for i, j in info:
    nemat[i][j] = 0
    nemat[j][i] = 0
    dfs(0, [False] * N)
    nemat[i][j] = 1
    nemat[j][i] = 1
print(ans)

class Unionfind:
    __slots__ = ["nodes"]

    def __init__(self, n):
        self.nodes = [-1] * n

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

    def unite(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return
        rank_x = -self.nodes[x]
        rank_y = -self.nodes[y]
        if rank_x < rank_y:
            x, y = y, x
        if rank_x == rank_y:
            self.nodes[x] -= 1
        self.nodes[y] = x

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

    def rank(self, x):
        return -self.nodes[self.root(x)]


N, M = list(map(int, input().split()))
info = [list(map(int, input().split())) for i in range(M)]


def bridge(k):
    uf = Unionfind(N)
    for i, pair in enumerate(info):
        if i == k:
            continue
        a = pair[0] - 1
        b = pair[1] - 1
        uf.unite(a, b)
    s = {uf.root(i) for i in range(N)}
    if len(s) != 1:
        return True
    return False


cnt = 0
for k in range(M):
    if bridge(k):
        cnt += 1
print(cnt)

-def multival(): -    return list(map(int, input().split())) +class Unionfind: +    __slots__ = ["nodes"] + +    def __init__(self, n): +        self.nodes = [-1] * n + +    def root(self, x): +        if self.nodes[x] < 0: +            return x +        else: +            root_x = self.root(self.nodes[x]) +            self.nodes[x] = root_x +            return root_x + +    def unite(self, x, y): +        x = self.root(x) +        y = self.root(y) +        if x == y: +            return +        rank_x = -self.nodes[x] +        rank_y = -self.nodes[y] +        if rank_x < rank_y: +            x, y = y, x +        if rank_x == rank_y: +            self.nodes[x] -= 1 +        self.nodes[y] = x + +    def same(self, x, y): +        return self.root(x) == self.root(y) + +    def rank(self, x): +        return -self.nodes[self.root(x)] -def data(N=1): -    return [list(map(int, input().split())) for _ in range(N)] +N, M = list(map(int, input().split())) +info = [list(map(int, input().split())) for i in range(M)] -mod = 10**9 + 7 -inf = float("inf") -N, M = multival() -nemat = [[0] * N for _ in range(N)] -ans = M -info = [] -for _ in range(M): -    a, b = multival() -    a -= 1 -    b -= 1 -    nemat[a][b] = 1 -    nemat[b][a] = 1 -    info.append([a, b]) +def bridge(k): +    uf = Unionfind(N) +    for i, pair in enumerate(info): +        if i == k: +            continue +        a = pair[0] - 1 +        b = pair[1] - 1 +        uf.unite(a, b) +    s = {uf.root(i) for i in range(N)} +    if len(s) != 1: +        return True +    return False -def dfs(now, visited): -    visited[now] = True -    if all(visited): -        global ans -        ans -= 1 -        return -    for ne in range(N): -        if nemat[now][ne] == 1 and visited[ne] is False: -            dfs(ne, visited) - - -for i, j in info: -    nemat[i][j] = 0 -    nemat[j][i] = 0 -    dfs(0, [False] * N) -    nemat[i][j] = 1 -    nemat[j][i] = 1 -print(ans) +cnt = 0 +for k in range(M): +    if bridge(k): +        cnt += 1 +print(cnt)