Problem:
 Score : 300 points    Problem Statement You are given an undirected connected graph with N vertices and M edges that does not contain self-loops and double edges. The i -th edge (1 \leq i \leq M) connects Vertex a_i and Vertex b_i .  An edge whose removal disconnects the graph is called a bridge . Find the number of the edges that are bridges among the M edges.      Notes  A self-loop is an edge i such that a_i=b_i  (1 \leq i \leq M) .  Double edges are a pair of edges i,j such that a_i=a_j and b_i=b_j  (1 \leq i<j \leq M) .  An undirected graph is said to be connected when there exists a path between every pair of vertices.       Constraints  2 \leq N \leq 50  N-1 \leq M \leq min(N(N−1)⁄2,50)  1 \leq a_i<b_i \leq N  The given graph does not contain self-loops and double edges.  The given graph is connected.         Input Input is given from Standard Input in the following format:  N  M  a_1  b_1  a_2  b_2  :  a_M  b_M       Output Print the number of the edges that are bridges among the M edges.        Sample Input 1 7 7
1 3
2 7
3 4
4 5
4 6
5 6
6 7      Sample Output 1 4  The figure below shows the given graph:     The edges shown in red are bridges. There are four of them.       Sample Input 2 3 3
1 2
1 3
2 3      Sample Output 2 0  It is possible that there is no bridge.       Sample Input 3 6 5
1 2
2 3
3 4
4 5
5 6      Sample Output 3 5  It is possible that every edge is a bridge.

Solution (Python):
import sys
n, m = [int(i) for i in sys.stdin.readline().split()]
graph = {j : [] for j in range(n)}
for i in range(m):
    a, b = [int(i) for i in sys.stdin.readline().split()]
    a -= 1
    b -= 1
    graph[a].append(b)
    graph[b].append(a)

result_ls = [[] for i in range(n)]
def dfs(pos, cnt, last):
    if len(result_ls[pos]) != 0:
        return result_ls[pos][1]
    res = cnt
    result_ls[pos] = [cnt, res]
    for candidate in graph[pos]:
        if candidate == last:
            continue
        _ = dfs(candidate, cnt + 1, pos)
        if _ < res:
            res = _
    result_ls[pos] = [cnt, res]
    return res

dfs(0, 0, -1)
cnt = 0
for res in result_ls:
    if res[0] > res[1]:
        cnt += 1
print(n - 1 - cnt)

Solution (Python):
import sys
from functools import reduce
import copy
import math
from pprint import pprint
import collections
import bisect


sys.setrecursionlimit(4100000)


def inputs(num_of_input):
    ins = [input() for i in range(num_of_input)]
    return ins


def int_inputs(num_of_input):
    ins = [int(input()) for i in range(num_of_input)]
    return ins


def solve(N, M, inputs):
    chains = list(map(string_to_int, inputs))
    nodes_chain = {i+1: set() for i in range(N)}

    for c in chains:
        [a, b] = c
        nodes_chain[a].add(b)
        nodes_chain[b].add(a)

    modified = True
    count = 0
    while modified:
        modified = False
        for node1 in nodes_chain.keys():
            target_nodes = nodes_chain[node1]
            if len(target_nodes) == 1:
                node2 = target_nodes.pop()
                nodes_chain[node2].remove(node1)
                count += 1
                modified = True
    return count


def string_to_int(string):
    return list(map(int, string.split()))


if __name__ == "__main__":
    [N, M] = string_to_int(input())
    ret = solve(N, M, inputs(M))
    print(ret)

Solution (Python):
import numpy as np
from scipy.sparse.csgraph import connected_components
from scipy.sparse import csr_matrix
def main():
    n,m=map(int,input().split(' '))
    graph=[[0 for i in range(n)] for j in range(n)]
    graph_del=[]
    ans = 0

    for i in range(m):
        e_1,e_2=map(int,input().split(' '))
        graph[e_1-1][e_2-1]=1
        graph[e_2-1][e_1-1]=1
        graph_del.append((e_1,e_2))

    for i,j in graph_del:
        graph[i-1][j-1]=0
        graph[j-1][i-1]=0
        if connected_components(np.array(graph),return_labels=False)!=1:
            ans += 1
        graph[i-1][j-1]=1
        graph[j-1][i-1]=1
    print(ans)




if __name__ == '__main__':
    main()

Solution (Python):
from scipy.sparse.csgraph import dijkstra
N, M = map(int, input().split())
edge = [list(map(int, input().split())) for _ in range(M)]

graph = [[0] * (N + 1) for _ in range(N + 1)]
for a, b in edge:
  graph[a][b] = 1

answer = 0
INF = 10 ** 9
for a, b in edge:
  
  graph[a][b] = INF
  dist = dijkstra(graph, indices = a, directed = False)
  if dist[b] >= INF:
    answer += 1
  
  graph[a][b] = 1

print(answer)

Solution (Python):
n,m=map(int,input().split())
edge=[]
from collections import deque
from collections import defaultdict
d=defaultdict(list)
for i in range(m):
    a,b=map(int,input().split())
    a-=1 
    b-=1 
    edge.append([a,b])
    d[a].append(b)
    d[b].append(a)
def check(d):
    q=deque()
    vis=[0]*n  
    q.append(0)
    vis[0]=1 
    while q:
        t=q.popleft()
        for i in d[t]:
            if not vis[i]:
                vis[i]=1 
                q.append(i)
    return sum(vis)==n 
cnt=0 
for a,b in edge:
    d[a].remove(b)
    d[b].remove(a)
    if not check(d): 
        cnt+=1 
    d[a].append(b)
    d[b].append(a)
print(cnt)

Solution (Python):
n, m = map(int, input().split())
graph = [[0] * n for _ in range(n)]  
edge = []
for i in range(m):
	a, b = map(int, input().split())
	graph[a-1][b-1] = 1
	graph[b-1][a-1] = 1
	edge.append([a-1,b-1])

def dfs(x):
	if(vis[x] == 1):
		return
	vis[x] = 1
	for i in range(n):
		if(graph[x][i] == 1):
			dfs(i)


ans = 0
for i in range(m):
	graph[edge[i][0]][edge[i][1]] = 0
	graph[edge[i][1]][edge[i][0]] = 0
	vis = [0] * 60
	dfs(0)
	for j in range(n):
		if(vis[j] == 0):
			ans += 1
			break
	graph[edge[i][0]][edge[i][1]] = 1
	graph[edge[i][1]][edge[i][0]] = 1
print (ans)

Solution (Python):
def dfs(v, N, graph, visited):
    visited[v] = True
    for v2 in range(N):
        if graph[v][v2] == False:
            continue
        if visited[v2] == True:
            continue
        dfs(v2, N, graph, visited)

N, M = map(int, input().split())
a, b = [], []
graph = [[False] * N for _ in range(N)]
for i in range(M):
    _a, _b = map(int, input().split())
    a.append(_a - 1), b.append(_b - 1)
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = True

ans = 0

for i in range(M):
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = False
    visited = [False] * N
    dfs(0, N, graph, visited)
    bridge = False
    for j in range(N):
        if visited[j] == False:
            bridge = True
    if bridge:
        ans += 1
    graph[a[i]][b[i]] = graph[b[i]][a[i]] = True

print(ans)

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

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

    def size(self, x):
        return -self.parents[self.find(x)]

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

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())
    
    

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

a = [0] * m
b = [0] * m

for i in range(m):
    a[i], b[i] = map(int,input().split())
    a[i]-= 1
    b[i]-= 1

res = 0
for i in range(m):
    UF = UnionFind(n)
    for j in range(m):
        if j != i:
            UF.union(a[j],b[j])
    if UF.group_count() ==2:
        res += 1

print(res)

Solution (Python):
from collections import defaultdict
n, m = map(int, input().split())
l = [tuple(map(int, input().split())) for i in range(m)]
graph = [[False] * n for i in range(n)]

for a, b in l:
    graph[a-1][b-1] = True
    graph[b-1][a-1] = True


def dfs(x):
    visited[x] = True
    for i in range(n):
        if graph[x][i] is False:
            continue
        if visited[i] is True:
            continue
        dfs(i)


ans = 0
for i in range(m):
    graph[l[i][0]-1][l[i][1]-1] = False
    graph[l[i][1]-1][l[i][0]-1] = False
    visited = [0] * n
    dfs(0)
    if sum(visited) != n:
        ans += 1
    graph[l[i][0]-1][l[i][1]-1] = True
    graph[l[i][1]-1][l[i][0]-1] = True
print(ans)

Solution (Python):
from collections import defaultdict
N, M = map(int, input().split())
dic = defaultdict(list)
ls = []
ans = 0
for i in range(M):
  a, b = map(int, input().split())
  dic[a] += [b]
  dic[b] += [a]
  ls += [(a,b)]

for v in ls:
  a, b = v
  stuck = [a]
  log = [True]*(N+1)
  log[a] = False
  count = 1
  while stuck:
    p = stuck.pop()
    if p==a or p==b:
      for e in dic[p]:
        if e==a or e==b:
          continue
        if log[e]:
          log[e] = False
          stuck += [e]
          count += 1
    else:
      for e in dic[p]:
        if log[e]:
          log[e] = False
          stuck += [e]
          count += 1
  if count != N:
    ans += 1

print(ans)

Solution (Python):
n,m=map(int,input().split())
e=[]
for i in range(m):
    e.append(list(map(int,input().split())))
ans=0
for i in range(m):
    g=[[] for _ in range(n)]
    for j in range(m):
        if i==j:
            continue
        g[e[j][0]-1].append(e[j][1])
        g[e[j][1]-1].append(e[j][0])
    visited=[0]*n
    visited[0]=1
    q=[1]
    while len(q)>0:
        a=q.pop(0)
        visited[a-1]=1
        for k in g[a-1]:
            if visited[k-1]==0:
                q+=[k]
    if sum(visited)!=n:
        ans+=1
print(ans)

Solution (Python):
from copy import deepcopy

WHITE = 0
GRAY = 1
BLACK = 2


def dfs(s, n, m):
    color = [WHITE] * n

    stack = [s]
    color[s] = GRAY
    while stack:
        u = stack[-1]
        for v, flg in enumerate(m[u]):
            if flg:
                if color[v] == WHITE:
                    color[v] = GRAY
                    stack.append(v)
                    break
        else:
            stack.pop()
            color[u] = BLACK

    cnt = color.count(BLACK)

    return cnt


def main():
    n, m = map(int, input().split())
    ab = [list(map(int, input().split())) for _ in range(m)]

    g = [[0] * n for _ in range(n)]
    for a, b in ab:
        a -= 1
        b -= 1
        g[a][b] = 1
        g[b][a] = 1

    ans = 0
    for a, b in ab:
        a -= 1
        b -= 1
        cp = deepcopy(g)
        cp[a][b] = 0
        cp[b][a] = 0

        cnt = dfs(0, n, cp)

        if cnt != n:
            ans += 1

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
n, m = map(int, input().split())
ab = [tuple(map(int, input().split())) for _ in range(m)]

graph = {x:[] for x in range(1, n+1)}
for x, y in ab:
    graph[x].append(y)
    graph[y].append(x)

def dfs(v):
    visited.append(v)
    for v2 in graph[v]:
        if v2 not in visited:
            dfs(v2)

res = 0
for a, b in ab:
    graph[a].remove(b)
    graph[b].remove(a)
    visited = []
    dfs(1)
    if len(visited) != n:
        res += 1
    graph[a].append(b)
    graph[b].append(a)

print(res)

Solution (Python):
n, m = map(int, input().split())
ab = [tuple(map(int, input().split())) for _ in range(m)]

graph = {x:[] for x in range(1, n+1)}
for x, y in ab:
    graph[x] = graph.get(x, []) + [y]
    graph[y] = graph.get(y, []) + [x]

res = 0
for a, b in ab:
    graph[a].remove(b)
    graph[b].remove(a)
    stack = [1]
    visited = []
    while len(stack) > 0:
        v = stack.pop()
        visited.append(v)
        for next in graph[v]:
            if next in visited:
                continue
            if next in stack:
                continue
            stack.append(next)
    if len(visited) != n:
        res += 1
    graph[a].append(b)
    graph[b].append(a)

print(res)

Solution (Python):
from collections import deque

n,m = map(int,input().split())
nodes = [[] for _ in range(n)]
edges = []
for _ in range(m):
    a,b = map(lambda x:int(x) -1,input().split())
    nodes[a].append(b)
    nodes[b].append(a)
    edges.append((a,b))
ans = 0
for a,b in edges:
    s = deque()
    gone = [0 for _ in range(n)]
    gone[a] = 1
    s.append(a)
    judge = 1
    while s:
        ai = s.popleft()
        for bi in nodes[ai]:
            if (ai,bi) == (a,b):
                pass
            elif bi ==b:
                judge =0
                break
            else:
                if gone[bi]==0:
                    s.append(bi)
                    gone[bi] =1
    if judge:
        ans +=1
print(ans)

Solution (Python):
N, M = list(map(int, input().split()))
lines = [list(map(int, input().split())) for _ in range(M)]

graph = [[False] * N for _ in range(N)]
for a,b in lines:
    graph[a-1][b-1] = graph[b-1][a-1] = True

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

def DFS(v):
    visited[v] = True
    for from_v in range(N):
        if not graph[v][from_v]:
            continue
        if visited[from_v]:
            continue
        DFS(from_v)
    
cnt = 0
for i in range(M):
    pass_a, pass_b = lines[i]
    pass_a -= 1
    pass_b -= 1
    graph[pass_a][pass_b] = graph[pass_b][pass_a] = False
    DFS(pass_a)
    
    cnt += 1 if False in visited else 0
    
    visited = [False for _ in range(N)]
    graph[pass_a][pass_b] = graph[pass_b][pass_a] = True

print(cnt)

Solution (Python):
from collections import deque
N,M = map(int,input().split())
G = {i:[] for i in range(1,N+1)}
Gd = {i:[] for i in range(1,N+1)}
for _ in range(M):
    a,b = map(int,input().split())
    G[a].append(b)
    G[b].append(a)
    Gd[a].append(b)
    Gd[b].append(a)
cnt = 0
for a in range(1,N+1):
    for b in G[a]:
        Gd[a].remove(b)
        Gd[b].remove(a)
        hist = [0 for _ in range(N+1)]
        stack = deque([1])
        while stack:
            cur = stack.popleft()
            hist[cur]=1
            for x in Gd[cur]:
                if hist[x]==0:
                    stack.append(x)
        if sum(hist)<N:
            cnt += 1
        Gd[a].append(b)
        Gd[b].append(a)
print(cnt//2)

Solution (Python):
N,M = tuple(map(int,input().split()))
from collections import defaultdict
graph = defaultdict(list)
edges = []
for i in range(M):
  a,b = tuple(map(int,input().split()))
  graph[a].append(b)
  graph[b].append(a)
  edges += [(a,b)]
  

res = 0

def search_path(from_node,to_node):
  queue = [(from_node,set())]
  while queue:
    now, prevs = queue.pop()
    for next_node in graph[now]:
      if {now,next_node} != {from_node,to_node} :
        if next_node == to_node:
          
          return 0
        if next_node not in prevs|{from_node,to_node}:
          queue.append((next_node, prevs|{now}))
  else:
    return 1

print(sum([search_path(from_node,to_node)	for from_node,to_node in edges]))

Solution (Python):
N,M = map(int,input().split())

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

for i in range(M):
    a[i],b[i] = map(int,input().split())
    a[i] -= 1
    b[i] -= 1

count = 0
for k in range(M):
    con = [[] for _ in range(N)]
    for i in range(M):
        if i != k:
            con[a[i]].append(b[i])
            con[b[i]].append(a[i])
    visited = [0] * N
    stack = [[0,0]]
    while stack:
        cur,pre = stack.pop()
        if visited[cur] == 1:
            continue
        visited[cur] = 1
        for x in con[cur]:
            if x != pre:
                stack.append([x,cur])
    
    if 0 in visited:
        count += 1

print(count)

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.par = [-1 for i in range(n)]

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

    def unite(self, x, y):
        x, y = self.root(x), self.root(y)
        if x != y:
            if self.par[x] > self.par[y]: 
                x, y = y, x
            self.par[x] += self.par[y]
            self.par[y] = x

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

    def size(self, x):
        return -self.par[self.root(x)]

n, m = map(int, input().split())
edges = []
for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    edges.append( (a, b) )

ans = 0
for i in range(m):
    uf = UnionFind(n)
    for j in range(m):
        if i == j:
            continue
        uf.unite(edges[j][0], edges[j][1])

    is_bridge = False
    for j in range(1, n):
        if not uf.same(j-1, j):
            is_bridge = True
            break

    if is_bridge:
        ans += 1

print(ans)

Solution (Python):
import collections
N, M = map(int, input().split())
a = [0]*M
b = [0]*M
table = collections.defaultdict(list)
for i in range(M):
    a[i], b[i] = map(int, input().split())
    table[a[i]].append(b[i])
    table[b[i]].append(a[i])
bridge = []
for x in table:
    if len(table[x]) < 2:
        bridge.append(x)
prev = 0
now = len(bridge)
while(prev != now):
    for x in table:
        if x not in bridge:
            lenx = len(table[x])
            for y in table[x]:
                if y in bridge:
                    lenx -= 1
            if lenx < 2:
                bridge.append(x)
    prev = now
    now = len(bridge)
ans = 0
for i in range(M):
    if a[i] in bridge or b[i] in bridge:
        ans += 1

print(ans)

Solution (Python):
N,M= map(int,input().split())
list=[[False for i in range(N)] for j in range(N)]
for i in range (M):
    a,b=map(int,input().split())
    list[a-1][b-1]=True
    list[b-1][a-1]=True
pre = [N for i in range(N)]
low = [N for i in range(N)]
precount=0
count = 0
flag = [False for i in range(N)]
flag[0]=True

def bridge_search (prev,now):
    global precount
    global count
    global flag
    pre[now] = precount
    low[now] = precount
    precount += 1
    flag[now] = True
    for i in range(0,N):
        if(list[now][i] and i != prev):
            if(not flag[i]):
                if bridge_search(now,i):
                    count += 1
                if low[i] < low[now] and pre[i] > pre[now]:
                    low[now] = low[i]
            else:
                if low[i] < low[now]:
                    low[now] = low[i]
    
    if low[now] >= pre[now]:
        return True
    else:
        return False
    
        
bridge_search(0,0)
print(count)

Solution (Python):
class UnionFind():
    
    
    def __init__(self, n):
        self.n = n
        
        
        self.root = [-1]*(n+1)
        
        self.rnk = [0]*(n+1)

    
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            
            self.root[x] = self.Find_Root(self.root[x])
            return self.root[x]
    
    def Unite(self, x, y):
        
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        
        if(x == y):
            return 
        
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            
            if(self.rnk[x] == self.rnk[y]):
                self.rnk[y] += 1
    
    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)

    
    def Count(self, x):
        return -self.root[self.Find_Root(x)]
      
N,M = map(int,input().split())
Edge = []
for i in range(M):
  a,b = map(int,input().split())
  Edge.append([a-1,b-1])

ans = 0
for i in range(M):
 graph = UnionFind(N)
 for j in range(M):
   if(i != j): 
    graph.Unite(Edge[j][0],Edge[j][1])
 if(graph.Count(0) != N): ans += 1
print(ans)

Solution (Python):
from scipy.sparse.csgraph import floyd_warshall

n,m=map(int,input().split())
l=[list(map(int,input().split())) for i in range(m)]

ans=0
for i in range(m):
    ll=l[:i]+l[i+1:]

    d=[[float('inf')]*n for i in range(n)]
    for i in range(n):
        d[i][i]=0

    for j in ll:
        d[j[0]-1][j[1]-1]=1
        d[j[1]-1][j[0]-1]=1

    d=floyd_warshall(d)

    if float('inf') in d:
        ans+=1

print(ans)

Solution (Python):
n,m = map(int,input().split())
master = [list(map(int,input().split())) for _ in range(m)]

def dfs(s):
    global flag
    global a
    if not flag[s]:
        flag[s] = True
    for g in a[s]:
        if not flag[g]:
            dfs(g)

res = 0
for i in range(m):
    a = [[] for _ in range(n)]
    for j in range(m):
        if j == i:
            continue
        else:
            a[master[j][0]-1].append(master[j][1]-1)
            a[master[j][1]-1].append(master[j][0]-1)
    
    flag = [False for _ in range(n)]

    dfs(master[i][0] -1)

    if not all(flag):
        res += 1

print(res)

Solution (Python):
n,m = map(int,input().split())
Edge = [list(map(int,input().split())) for i in range(m)]

count = 0

for i in range(m):
    Edge_ = Edge[:i]+Edge[i+1:]

    Graph = [[] for i in range(n)]
    for edge in Edge_:
        Graph[edge[0]-1].append(edge[1]-1)
        Graph[edge[1]-1].append(edge[0]-1)

    visited = [False]*n
    visited[0] = True

    stack = [0]
    while stack:
        node = stack.pop()
        for adj in Graph[node]:
            if visited[adj] == False:
                visited[adj] = True
                stack.append(adj)
                
    if not all(visited):
        count += 1
        
print(count)

Solution (Python):
N,M = map(int,input().split())
graph = [[0]*N for _ in range(N)]
Edge = []

for i in range(M):
  a,b = map(int,input().split())
  graph[a-1][b-1] = 1
  graph[b-1][a-1] = 1
  Edge.append([a-1,b-1])

def dfs(x):
  if(vis[x] == 1): return
  vis[x] = 1
  for i in range(N):
    if(graph[x][i] == 1):
      dfs(i)

ans = 0      
for i in range(M):
  graph[Edge[i][0]][Edge[i][1]] = 0
  graph[Edge[i][1]][Edge[i][0]] = 0
  vis = [0]*60
  dfs(0)
  for j in range(N):
    if(vis[j] == 0):
      ans += 1
      break
  graph[Edge[i][0]][Edge[i][1]] = 1
  graph[Edge[i][1]][Edge[i][0]] = 1
print(ans)

Solution (Python):
import copy

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

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

for _ in range(M):
    a, b = map(int, input().split())
    neighbor[a-1][b-1] = 1
    neighbor[b-1][a-1] = 1
    edge.append([a-1,b-1])


def visit_points(current_point):
    visited[current_point] = 1
    neighbor_point = [x for x in range(len(tmp_neighbor[current_point])) if tmp_neighbor[current_point][x] > 0]
    for np in neighbor_point:
        if visited[np] == 0:
            visit_points(np)


n_bridge = 0

for idx in range(M):
    tmp_neighbor = copy.deepcopy(neighbor)
    tmp_neighbor[edge[idx][0]][edge[idx][1]] = 0
    tmp_neighbor[edge[idx][1]][edge[idx][0]] = 0

    visited = [0]*N
    visit_points(0)
    if sum(visited) < N:
        n_bridge += 1

print(n_bridge)

Solution (Python):
from collections import deque

n,m=map(int,input().split())
l=[list(map(int,input().split())) for i in range(m)]

ans=0
for i in range(m):
    ll=l[:i]+l[i+1:]
    tree=[[] for i in range(n)]
    for i in ll:
        tree[i[0]-1].append(i[1]-1)
        tree[i[1]-1].append(i[0]-1)
    seen=[]
    seen.append(0)
    dq=deque()
    dq.append(0)
    cnt=1
    while dq:
        x=dq.pop()
        for i in tree[x]:
            if i not in seen:
                seen.append(i)
                dq.append(i)
                cnt+=1
    if cnt!=n:
        ans+=1
print(ans)

Solution (Python):
from collections import deque
N, M = map(int, input().split())

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

for m in range(M):
    a, b = map(int, input().split())
    graph[a].add(b)
    graph[b].add(a)
    edge.append([a, b])

ans = 0
for m in range(M):
    Bridge = True
    fr, to = edge[m][0], edge[m][1]
    V = {fr} | set(graph[fr]) - {to}
    que = deque(set(graph[fr]) - {to})
    while que:
        node = que.pop()
        for new_node in graph[node]:
            if new_node == to:
                Bridge = False
                break
            if new_node not in V:
                que.append(new_node)
                V.add(new_node)
        else:
            continue
        break
    if Bridge:
        ans += 1
print(ans)

Solution (Python):
from collections import deque
N, M = map(int, input().split())

graph = [set() for _ in range(N + 1)]
edge = []
for m in range(M):
    a, b = map(int, input().split())
    graph[a].add(b)
    graph[b].add(a)
    edge.append([a, b])

ans = 0
for m in range(M):
    Bridge = True
    fr, to = edge[m][0], edge[m][1]
    V = {fr} | set(graph[fr]) - {to}
    que = set(graph[fr]) - {to}
    while que:
        node = que.pop()
        for new_node in graph[node]:
            if new_node == to:
                Bridge = False
                break
            if new_node not in V:
                que.add(new_node)
                V.add(new_node)
        else:
            continue
        break
    if Bridge:
        ans += 1
print(ans)

Solution (Python):
N,M = map(int,input().split())

graph = [[0] * N for _ in range(N)] 
Edge = [] 
for i in range(M):
  a,b = map(int,input().split())
  graph[a-1][b-1] = 1
  graph[b-1][a-1] = 1
  Edge.append([a-1,b-1])
  
def dfs(x): 
  if(vis[x] == 1): return
  vis[x] = 1
  for i in range(N):
    if(graph[x][i] == 1):
     dfs(i)


ans = 0
for i in range(M):
 graph[Edge[i][0]][Edge[i][1]] = 0 
 graph[Edge[i][1]][Edge[i][0]] = 0 
 vis = [0]*60 
 dfs(0) 
 for j in range(N): 
    if(vis[j] == 0): 
     ans += 1 
     break
 graph[Edge[i][0]][Edge[i][1]] = 1 
 graph[Edge[i][1]][Edge[i][0]] = 1 
print(ans)

Solution (Python):
n, m = map(int, input().split())
ab = []
for i in range(m):
    ai, bi = map(int, input().split())
    ab.append([ai, bi])

def check_1(ab_lists):
    while True:
        if len(ab_lists) == 1:
            if len(ab_lists[0]) == n:
                return True
            else:
                return False
        if len(ab_lists) == 2 and len(ab_lists[0]) + len(ab_lists[1]) == len(set(ab_lists[0] + ab_lists[1])):
            return False
        for i in range(len(ab_lists)):
            flag = 0
            for j in range(i+1, len(ab_lists)):
                if len(ab_lists[i]) + len(ab_lists[j]) != len(set(ab_lists[i] + ab_lists[j])):
                    ab_lists[i] = list(set(ab_lists[i] + ab_lists[j]))
                    flag = 1
                    break
            if flag == 1:
                ab_lists.pop(j)
                break

res = 0
for i in range(m):
    ab_lists = ab[:i] + ab[i+1:]
    ret = check_1(ab_lists)
    if not ret:
        res += 1
print(res)

Solution (Python):
n, m = map(int, input().split())
edge = []
graph = [[False]*n for _ in range(n)]
visited = [False]*n
for i in range(m):
  a, b = map(int, input().split())
  edge.append((a, b))
  graph[a-1][b-1] = True
  graph[b-1][a-1] = True

def dfs(v):
  visited[v] = True
  for v2 in range(n):
    if graph[v][v2] == False:
      continue
    if visited[v2] == True:
      continue
    dfs(v2)

ans = 0
for _, e in enumerate(edge):
  graph[e[0]-1][e[1]-1] = False
  graph[e[1]-1][e[0]-1] = False

  for j in range(n):
    visited[j] = False

  dfs(0)

  bridge = False
  for j in range(n):
    if not all(visited):
      bridge = True
  if bridge:
    ans += 1

  graph[e[0]-1][e[1]-1] = True
  graph[e[1]-1][e[0]-1] = True

print(ans)

Solution (Python):
from collections import deque
n,m = map(int,input().split())
graph = [[] for _ in range(n)]
deg = [0]*n
seen = [False]*n
for i in range(m):
    x,y = map(int,input().split())
    graph[x-1] += [y-1]
    graph[y-1] += [x-1]
    deg[x-1] += 1
    deg[y-1] += 1
q = deque([i for i in range(n) if deg[i] == 1])
while q:
    v = q.popleft()
    seen[v] = True
    for i in graph[v]:
        deg[i] -= 1
        if deg[i] == 1:
            q.append(i)
if all(seen[i] == 1 for i in range(n)):print(n-1);exit()
print(seen.count(1))

Solution (Python):


from collections import deque

def Connected(g, nodenum):
    visited = [False]*nodenum
    que = deque([])
    posi = 0
    que.append(posi)
    while que:
        visit = que.pop()
        visited[visit] = True
        for goto in g[visit]:
            if visited[goto]:
                continue
            que.append(goto)
    if all(visited):
        return True
    else:
        return False

n, m = map(int, input().split())
g = [[] for _ in range(n)]
edge_log = []
for _ in range(m):
    a, b = map(int, input().split())
    g[a-1].append(b-1)
    g[b-1].append(a-1)
    edge_log.append((a-1, b-1))

ans = 0
for edge in edge_log:
    g[edge[0]].remove(edge[1])
    g[edge[1]].remove(edge[0])
    if not Connected(g, nodenum=n):
        ans += 1
    g[edge[0]].append(edge[1])
    g[edge[1]].append(edge[0])
print(ans)

Solution (Python):
from collections import deque
n,m= map(int,input().split())
graph = [[]for _ in range(n)]
deg = [0 for _ in range(n)]
for i in range(m):
    x,y = map(int,input().split())
    graph[x-1] += [y-1]
    graph[y-1] += [x-1]
    deg[x-1] += 1
    deg[y-1] += 1
q = deque([i for i in range(n) if deg[i] == 1])
seen = [False for _ in range(n)]

while q:
    v = q.popleft()
    seen[v] = True
    for i in graph[v]:
        deg[i] -= 1
        if deg[i] == 1:
            q.append(i)
if all(i for i in seen):print(n-1);exit()
print(seen.count(True))

Solution (Python):
from collections import deque

N, M = map(int, input().split())
edge = [[0 for i in range(N)] for i in range(N)]
edges = [(0,0) for i in range(M)]
ckd = [False for i in range(N)]
ans = 0


for i in range(M):
  a, b = map(int, input().split())
  edge[a-1][b-1] = 1
  edge[b-1][a-1] = 1
  edges[i] = (a-1, b-1)
  
for e in edges:
  edge[e[0]][e[1]] = 0
  edge[e[1]][e[0]] = 0
  
  q = deque()
  q.append(0)
  ckd = [False for i in range(N)]
  
  while q:
    r = q.popleft()
    for d in range(N):
      if edge[r][d] and not(ckd[d]):
        ckd[d] = True
        q.append(d)
        
  if not(all (c for c in ckd)):
    ans += 1
    
  edge[e[0]][e[1]] = 1
  edge[e[1]][e[0]] = 1
  
print(ans)

Solution (Python):

def find(parent, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, t)
    parent[i] = t
    return t


def unite(parent, i, j):
    i = find(parent, i)
    j = find(parent, j)
    if i == j:
        return
    parent[j] += parent[i]
    parent[i] = j


N, M = map(int, input().split())
ab = [[int(c) - 1 for c in input().split()] for _ in range(M)]

result = 0
for i in range(M):
    parent = [-1] * N
    for j in range(M):
        if j == i:
            continue
        unite(parent, ab[j][0], ab[j][1])
    if len([i for i in parent if i < 0]) != 1:
        result += 1
print(result)