import os

import sys



import numpy as np

from scipy.sparse import csr_matrix

from scipy.sparse.csgraph import connected_components



if os.getenv("LOCAL"):

    sys.stdin = open("_in.txt", "r")



sys.setrecursionlimit(2147483647)

INF = float("inf")

IINF = 10 ** 18

MOD = 10 ** 9 + 7



N, M = list(map(int, sys.stdin.readline().split()))

A, B = list(zip(*[list(map(int, sys.stdin.readline().split())) for _ in range(M)]))

A = np.array(A) - 1

B = np.array(B) - 1





def is_bridge(i):

    a = np.concatenate([A[:i], A[i + 1:]])

    b = np.concatenate([B[:i], B[i + 1:]])

    graph = csr_matrix(([True] * (M - 1), (a, b)), shape=(N, N))

    _, components = connected_components(graph, directed=False)

    return components.max() >= 1





ans = 0

for i in range(M):

    ans += is_bridge(i)

print(ans)

import os



import sys



if os.getenv("LOCAL"):

    sys.stdin = open("_in.txt", "r")



sys.setrecursionlimit(10 ** 9)

INF = float("inf")

IINF = 10 ** 18

MOD = 10 ** 9 + 7





# MOD = 998244353





def enumerate_bridges(graph):

    """

    橋を列挙する

    http://nupioca.hatenadiary.jp/entry/2013/11/03/200006

    :param list of (list of int) graph:

    """

    N = len(graph)

    ret_bridges = []

    pres = [-1] * N

    lows = [-1] * N

    order = -1

    for v in range(N):

        if pres[v] >= 0:

            continue

        edges = [(None, v, True)]

        while edges:

            v, u, forward = edges.pop()

            if forward:

                if pres[u] >= 0:

                    # もう来たことがある

                    lows[v] = min(lows[v], lows[u])

                    continue

                edges.append((v, u, False))

                parent, v = v, u

                order += 1

                pres[v] = lows[v] = order

                for u in graph[v]:

                    if u == parent:

                        continue

                    edges.append((v, u, True))

            else:

                if v is None:

                    continue

                if lows[u] == pres[u]:

                    ret_bridges.append((v, u))

                lows[v] = min(lows[v], lows[u])

    return ret_bridges





N, M = list(map(int, sys.stdin.buffer.readline().split()))

AB = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(M)]

graph = [[] for _ in range(N + 1)]

for a, b in AB:

    graph[a].append(b)

    graph[b].append(a)

bridges = enumerate_bridges(graph)

print((len(bridges)))

import os
import sys
import numpy as np
from scipy.sparse import csr_matrix
from scipy.sparse.csgraph import connected_components

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")
sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10**18
MOD = 10**9 + 7
N, M = list(map(int, sys.stdin.readline().split()))
A, B = list(zip(*[list(map(int, sys.stdin.readline().split())) for _ in range(M)]))
A = np.array(A) - 1
B = np.array(B) - 1


def is_bridge(i):
    a = np.concatenate([A[:i], A[i + 1 :]])
    b = np.concatenate([B[:i], B[i + 1 :]])
    graph = csr_matrix(([True] * (M - 1), (a, b)), shape=(N, N))
    _, components = connected_components(graph, directed=False)
    return components.max() >= 1


ans = 0
for i in range(M):
    ans += is_bridge(i)
print(ans)

import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")
sys.setrecursionlimit(10**9)
INF = float("inf")
IINF = 10**18
MOD = 10**9 + 7
# MOD = 998244353
def enumerate_bridges(graph):
    """
    橋を列挙する
    http://nupioca.hatenadiary.jp/entry/2013/11/03/200006
    :param list of (list of int) graph:
    """
    N = len(graph)
    ret_bridges = []
    pres = [-1] * N
    lows = [-1] * N
    order = -1
    for v in range(N):
        if pres[v] >= 0:
            continue
        edges = [(None, v, True)]
        while edges:
            v, u, forward = edges.pop()
            if forward:
                if pres[u] >= 0:
                    # もう来たことがある
                    lows[v] = min(lows[v], lows[u])
                    continue
                edges.append((v, u, False))
                parent, v = v, u
                order += 1
                pres[v] = lows[v] = order
                for u in graph[v]:
                    if u == parent:
                        continue
                    edges.append((v, u, True))
            else:
                if v is None:
                    continue
                if lows[u] == pres[u]:
                    ret_bridges.append((v, u))
                lows[v] = min(lows[v], lows[u])
    return ret_bridges


N, M = list(map(int, sys.stdin.buffer.readline().split()))
AB = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(M)]
graph = [[] for _ in range(N + 1)]
for a, b in AB:
    graph[a].append(b)
    graph[b].append(a)
bridges = enumerate_bridges(graph)
print((len(bridges)))

-import numpy as np -from scipy.sparse import csr_matrix -from scipy.sparse.csgraph import connected_components -sys.setrecursionlimit(2147483647) +sys.setrecursionlimit(10**9) -N, M = list(map(int, sys.stdin.readline().split())) -A, B = list(zip(*[list(map(int, sys.stdin.readline().split())) for _ in range(M)])) -A = np.array(A) - 1 -B = np.array(B) - 1 +# MOD = 998244353 +def enumerate_bridges(graph): +    """ +    橋を列挙する +    http://nupioca.hatenadiary.jp/entry/2013/11/03/200006 +    :param list of (list of int) graph: +    """ +    N = len(graph) +    ret_bridges = [] +    pres = [-1] * N +    lows = [-1] * N +    order = -1 +    for v in range(N): +        if pres[v] >= 0: +            continue +        edges = [(None, v, True)] +        while edges: +            v, u, forward = edges.pop() +            if forward: +                if pres[u] >= 0: +                    # もう来たことがある +                    lows[v] = min(lows[v], lows[u]) +                    continue +                edges.append((v, u, False)) +                parent, v = v, u +                order += 1 +                pres[v] = lows[v] = order +                for u in graph[v]: +                    if u == parent: +                        continue +                    edges.append((v, u, True)) +            else: +                if v is None: +                    continue +                if lows[u] == pres[u]: +                    ret_bridges.append((v, u)) +                lows[v] = min(lows[v], lows[u]) +    return ret_bridges -def is_bridge(i): -    a = np.concatenate([A[:i], A[i + 1 :]]) -    b = np.concatenate([B[:i], B[i + 1 :]]) -    graph = csr_matrix(([True] * (M - 1), (a, b)), shape=(N, N)) -    _, components = connected_components(graph, directed=False) -    return components.max() >= 1 - - -ans = 0 -for i in range(M): -    ans += is_bridge(i) -print(ans) +N, M = list(map(int, sys.stdin.buffer.readline().split())) +AB = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(M)] +graph = [[] for _ in range(N + 1)] +for a, b in AB: +    graph[a].append(b) +    graph[b].append(a) +bridges = enumerate_bridges(graph) +print((len(bridges)))