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, math, fractions, itertools

def connected_num(N, G):
    
    visited = [0] * N
    stack = [0]
    while(len(stack) > 0):
        n = stack.pop()
        if visited[n] == 0:
            stack += G[n]
            visited[n] = 1
    return sum(visited) != N
def solve(N: int, M: int, a: "List[int]", b: "List[int]"):
    counter = 0
    for j in range(M):
        G = [[] for _ in range(N)]
        for i in list(range(j))+list(range(j+1, M)):
            G[a[i]-1].append(b[i]-1)
            G[b[i]-1].append(a[i]-1)
        if connected_num(N, G):
            counter += 1
    print(counter)
    return



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    M = int(next(tokens))  
    a = [int()] * (M)  
    b = [int()] * (M)  
    for i in range(M):
        a[i] = int(next(tokens))
        b[i] = int(next(tokens))
    solve(N, M, a, b)

if __name__ == '__main__':
    main()

Solution (Python):
def dfs(V,E):
    s[V-1]=1
    for i in Ren[V-1]:
        if E!={V,i} and s[i-1]==0:dfs(i,E)
N,M=map(int,input().split())
Edge=[list(map(int,input().split())) for i in range(M)]
Ren=[[] for i in range(N)]
for a,b in Edge:
    Ren[a-1].append(b)
    Ren[b-1].append(a)
ans=0
for i in Edge:
    s=[0]*N
    dfs(1,set(i))
    if 0 in s:ans+=1
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline


def solve(N, M, edges):
    def is_connected(es):
        e = [[False]*(N+1) for _ in range(N+1)]
        for a, b in es:
            e[a][b] = True
            e[b][a] = True

        visited = [False]*(N+1)
        s = [1]
        while len(s) > 0:
            v = s.pop()
            visited[v] = True
            for i in range(1, N+1):
                if e[v][i] and not visited[i]:
                    s.append(i)

        for v in range(1, N+1):
            if not visited[v]:
                return False

        return True

    bridge = 0
    for i in range(M):
        if not is_connected(edges[:i] + edges[i+1:]):
            bridge += 1

    return bridge


def main():
    N, M = map(int, input().split())
    edges = []
    for _ in range(M):
        a, b = map(int, input().split())
        edges.append((a, b))
    print(solve(N, M, edges))


if __name__ == "__main__":
    main()

Solution (Python):
N, M = map(int, input().split())
E = []
for _ in range(M):
    a, b = map(int, input().split())
    E.append((a, b))

E = sorted(E)

P = -1

def unionFind(E):
    parent = [i for i in range(N+1)]
    def root(a):
        p = a
        while parent[p] != p:
            p = parent[p]
        parent[a] = p
        return p
        
    for a, b in E:
        pa = root(a)
        pb = root(b)
        if pa < pb:
            parent[pb] = pa
        elif pa > pb:
            parent[pa] = pb

    for i in range(1, N+1):
        root(i)
    return max(parent)

def main():
    bridge = 0
    if M == 1:
        print(1)
    else:
        for i in range(0, M):
            if unionFind(E[:i]+E[i+1:]) != 1:
                bridge += 1
        print(bridge)
main()

Solution (Python):

import sys
from collections import defaultdict
INF = float("inf")


def solve(N: int, M: int, a: "List[int]", b: "List[int]"):

    edges = defaultdict(list)
    for f_, t_ in zip(a, b):
        edges[f_-1].append(t_-1)
        edges[t_-1].append(f_-1)

    visited = [False] * N

    def dfs(f_, pre):
        if visited[f_] is True:
            return True

        visited[f_] = True
        for t_ in edges[f_]:
            if t_ == pre:
                continue
            dfs(t_, f_)
        return

    counter = 0
    for f_, t_ in zip(a, b):
        edges[f_-1].remove(t_-1)
        edges[t_-1].remove(f_-1)
        visited = [False] * N
        dfs(0, -1)
        if all(visited) is False:
            counter += 1
        edges[f_-1].append(t_-1)
        edges[t_-1].append(f_-1)
    print(counter)

    return


def main():

    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    M = int(next(tokens))  
    a = [int()] * (M)  
    b = [int()] * (M)  
    for i in range(M):
        a[i] = int(next(tokens))
        b[i] = int(next(tokens))
    solve(N, M, a, b)


if __name__ == '__main__':
    main()

Solution (Python):
N, M = map(int, input().split())
graph = [[0 for i in range(N)] for j in range(N)]
edges = []
for m in range(M):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    edges.append([a,b])
    graph[a][b] = 1
    graph[b][a] = 1

ans = 0
for a,b in edges:
    graph[a][b] = 0
    graph[b][a] = 0

    visited = [False] * N
    visited[0] = True
    q = [i for i in range(N) if graph[0][i]]

    while q:
        r = q.pop(0)
        visited[r] = True
        for i in range(N):
            if graph[r][i] and not visited[i]:
                q.append(i)

    if False in visited:
        ans += 1

    graph[a][b] = 1
    graph[b][a] = 1

print(ans)

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

def check(l):
    r=[False]*(n+1)
    r[0]=True
    r[1]=True
    c=1
    while c>0:
        c=0
        for i in l:
            if r[a[i]]^r[b[i]]:r[a[i]]=True;r[b[i]]=True;c+=1
    if all(r):return True
    else: return False
c=0
for i in range(m):
    if not check(list(range(i))+list(range(i+1,m))):c+=1
print(c)

Solution (Python):
def BFS(L):
    Visit=[]
    now=[]

    L_temp=L.copy()
    Visit.extend(L_temp[0])
    now.extend(L_temp[0])

    L_temp.remove(L_temp[0])

    
    l_n=0
    while 0 < len(L_temp) and 0 < len(now):
        now_t=now[0]



        l=L_temp[l_n]
        l_n+=1



        for t_n in range(len(l)):
            t_n_r = 1-t_n
            if now_t == l[t_n] :
                if l[t_n_r] not in Visit:
                    Visit.append(l[t_n_r])
                now.append(l[t_n_r])
                L_temp.remove(l)
                l_n=0

        if l_n == len(L_temp):
            now=now[1:]
            l_n=0   
    
    return(Visit)

N,M=[int(x) for x in input().split()]
L=[]
for i in range(M):
    L.append([int(x) for x in input().split()])




ans=0
for l in range(len(L)):
    L_temp=L.copy()
    L_temp.pop(l)
    
    visit=BFS(L_temp)
    len_visit=len(visit)
    
    if len_visit!=N:
        ans+=1

print(ans)

Solution (Python):
import copy

n, m = map(int, input().split())
graph = {i + 1: [] for i in range(n)}
edge = []
for i in range(m):
    a, b = map(int, input().split())
    graph[a].append(b)
    graph[b].append(a)
    edge.append([a, b])
count = 0
for i in range(m):
    copy_graph = copy.deepcopy(graph)
    a, b = edge[i][0], edge[i][1]
    copy_graph[a].remove(b)
    copy_graph[b].remove(a)
    checked = set()
    check = [a]
    while check:
        test = check.pop(0)
        for j in copy_graph[test]:
            if j not in checked:
                check.append(j)
        checked |= {test,}
    if b not in checked:
        count += 1
print(count)

Solution (Python):
N, M = map(int, input().split())
graph = [[] for _ in range(N)]
line = []
for _ in range(M):
    a, b = map(int, input().split())
    line.append([a-1, b-1])
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)


ans = 0
for l in line:
    a, b = l
    qs = [a]
    checked = [False for _ in range(N)]
    checked[b] = True
    ok = False
    
    first = True
    while qs:
        
        qqs = []
        for q in qs:
            checked[q] = True
            for k in graph[q]:
                
                if k == b and first:
                    first = False
                elif k == b:
                    ok = True
                    break
                if not checked[k]:
                    qqs.append(k)
        qs = qqs
    if not ok:
        ans += 1

print(ans)

Solution (Python):
from collections import defaultdict,deque
def f(List,n):
    D[n]=1
    if List[n]==[]:return
    else:
        for i in List[n]:
            if D[i]==1:pass
            else:f(List,i)
    
N,M=map(int,input().split())
L=deque([[] for _ in range(N)]for _ in range(M))
for i in range(M):
    a,b=map(int,input().split())
    for j in range(M):
        if i==j:pass
        else:
            L[j][a-1].append(b-1)
            L[j][b-1].append(a-1)

ans=0
for k in range(M):
    List=L.popleft()
    D=defaultdict(int)
    f(List,0)
    judge=0
    for l in range(N):
        if D[l]==0:judge+=1
        else:pass
    if judge!=0:ans+=1
print(ans)

Solution (Python):

from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random
import itertools
sys.setrecursionlimit(10**5)
stdin = sys.stdin
bisect_left = bisect.bisect_left
bisect_right = bisect.bisect_right
def LI(): return list(map(int, stdin.readline().split()))
def LF(): return list(map(float, stdin.readline().split()))
def LI_(): return list(map(lambda x: int(x)-1, stdin.readline().split()))
def II(): return int(stdin.readline())
def IF(): return float(stdin.readline())
def LS(): return list(map(list, stdin.readline().split()))
def S(): return list(stdin.readline().rstrip())
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float('INF')
move = [(0, 1), (1, 1), (-1, 1), (0, -1), (1, -1), (-1, -1), (1, 0), (-1, 0)]

def A():
    a, b, c = LI()
    if a == b:
        print(c)
    if b == c:
        print(a)
    if a == c:
        print(b)
    return


def B():
    h, w = LI()
    s = SR(h)
    for y in range(h):
        for x in range(w):
            if s[y][x] == ".":
                b = 0
                for my, mx in move:
                    ym = my + y
                    xm = mx + x
                    if 0 <= ym < h and 0 <= xm < w:
                        if s[ym][xm] == "
                            b += 1
                s[y][x] = b
    for i in range(h):
        print("".join(map(str, s[i])))
    return


def C():
    n, m = LI()
    edg = [[] for i in range(n)]
    ab = LIR_(m)
    for a,b in ab:
        edg[a].append(b)
        edg[b].append(a)
    ans = 0
    for a, b in ab:
        c = [True] * n
        ed = defaultdict(int)
        q = deque()
        q.append(0)
        c[0] = False
        ed[(a,b)] = True
        while q:
            now = q.pop()
            for e in edg[now]:
                if ed[(now,e)] or ed[(e,now)]:
                    continue
                ed[(now, e)] = True
                c[e] = False
                q.appendleft(e)
        if True in c:
            ans += 1
    print(ans)
    return


def D():
    return


if __name__ == '__main__':
    C()

Solution (Python):
n, m = map(int, input().split())
edges = [list(map(int, input().split())) for i in range(m)]
ans = 0
for x in edges:
    l = list(range(n))
    for y in edges:
        if y != x:
            l = [l[y[0]-1] if l[i] == l[y[1]-1] else l[i] for i in range(n)]
    if len(set(l)) != 1:
        ans += 1
print(ans)

Solution (Python):
from collections import deque

def dfs(n,m,ls):
    stack = deque([1])
    visited = [0 for _ in range(n+1)]
    visited[0] = 1
    while stack:
        now = stack.pop()
        for i in range(1,n+1):
            if ls[now][i]==1 and visited[i]==0:
                stack.append(i)
        visited[now]=1
    if all(i==1 for i in visited):
        return True
    else:
        return False

if __name__ =="__main__":
    
    n,m = map(int,input().split())
    ls = [[0 for _ in range(n+1)] for _ in range(n+1)]
    ls_inputs = [[int(x) for x in input().split()] for _ in range(m)]
    ans = 0
    for j in range(m):
        ls = [[0 for _ in range(n+1)] for _ in range(n+1)]
        for k,path in enumerate(ls_inputs):
            if j == k:
                pass
            else:
                ls[path[0]][path[1]]=1
                ls[path[1]][path[0]]=1
        if dfs(n,m,ls):
            pass
        else:
            ans +=1
    print(ans)

Solution (Python):
from scipy.sparse.csgraph import dijkstra
N,M = map(int,input().split())
edge = [[int(x) for x in 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):
ans = 0

N, M = map(int, input().split())
graph = [[0 for i in range(N)] for j in range(N)]
route = []

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

    route.append((a, b))

for a, b in route:
    graph[a-1][b-1] = 0
    graph[b-1][a-1] = 0

    visited = [False] * N
    visited[0] = True
    q = [i for i in range(N) if graph[0][i]]

    while q:
        r = q.pop(0)
        visited[r] = True
        for i in range(N):
            if graph[r][i] and not visited[i]:
                q.append(i)

    if False in visited:
        ans += 1
    graph[a-1][b-1] = 1
    graph[b-1][a-1] = 1

print(ans)

Solution (Python):
from collections import deque
N, M = map(int, input().split())
D = []
ans = 0
for i in range(M):
  a,b = map(int, input().split())
  a -= 1
  b -= 1
  D.append((a,b))
for i in range(M):
  visited = [0]*N
  x,y = D.pop(i)
  C = [[] for i in range(N)]
  for j in range(M-1):
    a,b = D[j]
    C[a].append(b)
    C[b].append(a)
  H = deque()
  H.append(0)
  while H:
    e = H.popleft()
    if visited[e] == 0:
      visited[e] = 1
      for k in range(len(C[e])):
        H.append(C[e][k])
  D.insert(i,(x,y))
  if all(visited):
    continue
  else:
    ans += 1
print(ans)

Solution (Python):
class UnionFind:
    def __init__(self, num):
        self.rank = [0] * num
        self.par = [i for i in range(num)]
        self.n = num

    def find_root(self, node):
        if self.par[node] == node:
            return node
        else:
            self.par[node] = self.find_root(self.par[node])
            return self.par[node]

    def same_root(self, x, y):
        return self.find_root(x) == self.find_root(y)

    def union(self, x, y):
        x = self.find_root(x)
        y = self.find_root(y)
        if x == y:
            return
        if self.rank[x] > self.rank[y]:
            self.par[y] = x
        else:
            self.par[x] = y
            if self.rank[x] == self.rank[y]:
                self.rank[y] += 1


def main():
    N, M = map(int, input().split())
    L = [list(map(int,input().split())) for i in range(M)]
    for i in range(M) :
        L[i][0] -= 1
        L[i][1] -= 1
    
    ans = 0
    
    for i in range(M) :
        UF = UnionFind(N)
        for j in range(M) :
            if j == i :
                continue
            UF.union(L[j][0], L[j][1])
        
        ans += (UF.same_root(L[i][0], L[i][1]) == False)
    
    print(ans)

import sys
input = sys.stdin.readline

if __name__ == "__main__":
    main()

Solution (Python):
N, M = map(int,input().split())
A = []
B = []
for _ in range(M):
    a, b = map(int,input().split())
    a -= 1
    b -= 1
    A.append(a)
    B.append(b)

G = [[] for _ in range(N)]
for a, b in zip(A, B):
    G[a].append(b)
    G[b].append(a)

def dfs(F):
    E = []
    while F:
        v = F.pop()
        if v not in E:
            E.append(v)
        if len(E) == N:
            return True
        for e in G[v]:
            if e in E:
                continue
            F.append(e)

    return False

ans = 0
for a, b in zip(A, B):
    G[a].remove(b)
    G[b].remove(a)
    if not dfs([0]):
        ans += 1
    G[a].append(b)
    G[b].append(a)

print(ans)

Solution (Python):


from heapq import heappop,heappush

n,m=map(int,input().split())
edge=[[] for _ in range(n)]
del_edge=[]
cnt=0

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


def find(s,de):
    visited=[False]*n
    visited[s]=True
    que=[]
    for e in edge[s]:
        if s in de and e in de:continue
        heappush(que,e)
    while que: 
        v=heappop(que)
        if visited[v]:continue
        visited[v]=True
        for vtx in edge[v]:
            if v in de and vtx in de:continue
            if visited[vtx]:continue
            hq=vtx
            heappush(que,hq)

    if False in visited:
        return 1
    else:return 0

for i in range(m):
    tmp=del_edge[i]
    cnt+=find(0,tmp)

print(cnt)

Solution (Python):
from subprocess import*
with open('Main.java','w')as f:f.write(r"""
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;

public class Main {
	public static class Edge {
		int e1, e2;
		public Edge (int e1, int e2) {
			this.e1 = e1;
			this.e2 = e2;
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = Integer.parseInt(sc.next());
		int m = Integer.parseInt(sc.next());
		Edge[] c = new Edge[m];
		int ans = 0;
		for (int i = 0; i < m; i++)
			c[i] = new Edge(Integer.parseInt(sc.next()), Integer.parseInt(sc.next()));
		for (int i = 0; i < m; i++) {
			Edge[] d = new Edge[m - 1];
			for (int j = 0; j < i; j++)
				d[j] = c[j];
			for (int j = i; j < m - 1; j++)
				d[j] = c[j + 1];
			ans += search(n, d);
		}
		System.out.println(ans);
	}

	public static int search(int n, Edge[] d) {
		int[] already = new int[n + 1];
		Deque<Integer> p = new ArrayDeque<Integer>();
		already[d[0].e1] = 1;
		p.push(d[0].e1);
		int count = 1;
		while(!p.isEmpty()) {
			int here = p.pop();
			for (int i = 0; i < d.length; i++) {
				if (d[i].e1 == here && already[d[i].e2] != 1) {
					already[d[i].e2] = 1;
					p.push(d[i].e2);
					count++;
				}
				else if (d[i].e2 == here && already[d[i].e1] != 1) {
					already[d[i].e1] = 1;
					p.push(d[i].e1);
					count++;
				}
			}
		}
		if (count == n)
			return 0;
		else
			return 1;
	}
}
""")
call(('javac','Main.java'))
call(('java','Main'))

Solution (Python):
from subprocess import*
with open('Main.java','w')as f:f.write(r"""
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;

public class Main {
	public static class Edge {
		int e1, e2;
		public Edge (int e1, int e2) {
			this.e1 = e1;
			this.e2 = e2;
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = Integer.parseInt(sc.next());
		int m = Integer.parseInt(sc.next());
		Edge[] c = new Edge[m];
		int ans = 0;
		for (int i = 0; i < m; i++)
			c[i] = new Edge(Integer.parseInt(sc.next()), Integer.parseInt(sc.next()));
		for (int i = 0; i < m; i++) {
			Edge[] d = new Edge[m - 1];
			for (int j = 0; j < i; j++)
				d[j] = c[j];
			for (int j = i; j < m - 1; j++)
				d[j] = c[j + 1];
			ans += search(n, d);
		}
		System.out.println(ans);
	}

	public static int search(int n, Edge[] d) {
		int[] already = new int[n + 1];
		Deque<Integer> p = new ArrayDeque<Integer>();
		already[d[0].e1] = 1;
		p.push(d[0].e1);
		int count = 1;
		while(!p.isEmpty()) {
			int here = p.pop();
			for (int i = 0; i < d.length; i++) {
				if (d[i].e1 == here && already[d[i].e2] != 1) {
					already[d[i].e2] = 1;
					p.push(d[i].e2);
					count++;
				}
				else if (d[i].e2 == here && already[d[i].e1] != 1) {
					already[d[i].e1] = 1;
					p.push(d[i].e1);
					count++;
				}
			}
		}
		if (count == n)
			return 0;
		else
			return 1;
	}
}
""")
call(('javac','Main.java'))
call(('java','Main'))

Solution (Python):
n,m=map(int,input().split())

g=[[] for i in range(1+n)]
v=[0]*(1+n)
e=[]
for i in range(m):
    a,b=map(int,input().split())
    e.append((a,b))
    g[a].append(b)
    g[b].append(a)

def dfs(st,ed):
    q=[]
    q.append(st)

    while q:
        cur=q.pop()
        v[cur]=1
        if cur==ed:
            return True

        for nb in g[cur]:
            if v[nb]!=1 and (cur,nb)!=(st,ed):
                q.append(nb)
    return False

ans=0
for a,b in e:
    v=[0]*(1+n)
    if not dfs(a,b):
        ans+=1
print(ans)

Solution (Python):
n,m=map(int,input().split())

g=[[] for i in range(1+n)]
v=[0]*(1+n)
e=[]
for i in range(m):
    a,b=map(int,input().split())
    e.append((a,b))
    g[a].append(b)
    g[b].append(a)

def dfs(st,ed):
    q=[]
    q.append(st)

    while q:
        cur=q.pop()
        v[cur]=1
        if cur==ed:
            return True

        for nb in g[cur]:
            
            if v[nb]!=1 and (cur,nb)!=(st,ed):
                q.append(nb)
    
    return False

ans=0
for a,b in e:
    v=[0]*(1+n)
    
    if not dfs(a,b):
        ans+=1

print(ans)

Solution (Python):
class Node:
    def __init__(self, id):
        self.id = id
        self.link = []

def bfs(node, check, ban_a, ban_b):
    check[node.id] = True
    ret = 1
    ban = -1
    if node.id == ban_a:
        ban = ban_b
    elif node.id == ban_b:
        ban = ban_a
    for next in node.link:
        if not check[next.id] and next.id != ban:
            ret += bfs(next, check, ban_a, ban_b)
    return ret





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

nodes = [Node(i) for i in range(N)]

for i in range(M):
    a, b = ab[i]
    a -= 1; b -= 1;
    nodes[a].link.append(nodes[b])
    nodes[b].link.append(nodes[a])

ans = 0
root = nodes[0]
for i in range(M):
    a, b = ab[i]
    a -= 1; b -= 1;
    check = [False] * N
    if N != bfs(root, check, a, b):
        ans += 1
print(ans)

Solution (Python):
N,M=map(int,input().split())
ab=[list(map(int,input().split())) for _ in [0]*M]
g=[set() for _ in [0]*N]
[g[b-1].add(a-1) for a,b in ab]
[g[a-1].add(b-1) for a,b in ab]
q=[i for i,gg in enumerate(g) if len(gg)==1]
cnt=0
while(q):
    cnt+=len(q)
    for i in q:
        g[i]=set()
        for j in range(N):
            g[j]=g[j]-{i}
    q=[i for i,gg in enumerate(g) if len(gg)==1]
print(min(cnt,M))

Solution (Python):


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

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

list_edge = []

for _ in range(M):
    a, b = map(int, input().split())
    list_edge.append((a, b))
    list_adjlist[a].append(b)
    list_adjlist[b].append(a)

def FIFO(list_FIFO, node):
    if node != None:
        list_FIFO.append(node)
        return None
    return list_FIFO.pop(0)


all_bridge = 0


for u, v in list_edge:
    
    uv_bridge = 1
    
    list_FIFO = []
    
    list_check = [False] * (N + 1)
    
    FIFO(list_FIFO, u)
    
    list_check[u] = True
    
    while list_FIFO != [] and list_FIFO[-1] != v:
        
        node = FIFO(list_FIFO, None)
        
        for adjnode in list_adjlist[node]:
            
            if list_check[adjnode]:
                
                continue
            
            if adjnode == v:
                
                if node != u:  
                    
                    uv_bridge = 0
                    
                    FIFO(list_FIFO, adjnode)
                    
                    break
            
            else:
                
                FIFO(list_FIFO, adjnode)
                
                list_check[adjnode] = True
    
    all_bridge += uv_bridge
                

print(all_bridge)

Solution (Python):



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

graph = [[] for _ in range(n)]
edge = []
for i in range(m):
    a,b = map(int,input().split())
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)
    edge.append([a,b])
def dfs(g,s):
    c[s] = True
    for i in g[s]:
        if not c[i]:
            c[i] = True
            dfs(g,i)

check = [False]*n
ans = 0
for a,b in edge:
    c = check.copy()
    g = copy.deepcopy(graph)
    g[a-1].remove(b-1)
    g[b-1].remove(a-1)
    dfs(g,0)
    if False in c:
        ans += 1
print(ans)

Solution (Python):

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

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

list_edge = []

for _ in range(M):
    a, b = map(int, input().split())
    list_edge.append((a, b))
    list_adjlist[a].append(b)
    list_adjlist[b].append(a)
    

bridge = 0


for a, b in list_edge:
    
    list_node = list_adjlist[a].copy()
    list_node.remove(b)
    
    set_visit_node = {a}
    
    while True:
        
        set_next_node = set()
        
        for v in list(list_node):
            
            set_next_node |= set(list_adjlist[v])
        
        set_visit_node |= set(list_node)
        
        if set_next_node.issubset(set_visit_node):
            break
        
        else:
            
            list_node = list(set_next_node - set_visit_node)
    
    if b not in set_visit_node:
        bridge += 1


print(bridge)

Solution (Python):
n,m=map(int,input().split())
c=[[] for _ in range(n+1)]
for i in range(m):
    a,b=map(int,input().split())
    c[a].append(b)
    c[b].append(a)
def des(c,res):
    for i in range(1,n+1):
        if len(c[i])==1:
            c[c[i][0]].remove(i)
            c[i]=[]
            res=des(c,res+1)
    return res
print(des(c,0))

Solution (Python):
from sys import stdin
N, M = [int(_) for _ in stdin.readline().rstrip().split()]

class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [0]*n
        self.size = [1]*n


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

    def merge(self, x, y):
        x, y = self.find_root(x), self.find_root(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1


    def issame(self, x, y):
        return self.find_root(x) == self.find_root(y)


    def get_size(self, x):
        x = self.find_root(x)
        return self.size[x]

ans = 0
data = []
for i in range(M):
    a, b = [int(_) for _ in stdin.readline().rstrip().split()]
    a, b = a-1, b-1
    data.append((a, b))

for i in range(M):
    uf = UnionFind(N)
    for j in range(M):
        if i == j:
            continue
        uf.merge(data[j][0], data[j][1])
    flag = False
    for j in range(N):
        if not uf.issame(0, j):
            flag = True
    if flag:
        ans += 1

print(ans)

Solution (Python):
n,m=map(int,input().split())
graph=[[False]*n for i in range(n)] 
node=[None for i in range(m)]
visited=[False]*n 
for i in range(m):
    a,b=map(int,input().split())
    graph[a-1][b-1],graph[b-1][a-1]=True,True
    node[i]=[a-1,b-1]
def dfs(v):
    visited[v]=True
    for i in range(n):
        if graph[v][i]==False:continue
        if visited[i]==True:continue
        dfs(i)
ans=0
for i in range(m):
    graph[node[i][0]][node[i][1]],graph[node[i][1]][node[i][0]]=False,False 
    for j in range(n):visited[j]=False
    dfs(0)
    for h in range(n):
        if visited[h]==False:
            ans+=1
            break
    graph[node[i][0]][node[i][1]],graph[node[i][1]][node[i][0]]=True,True
print(ans)

Solution (Python):
n,m=map(int,input().split())
v=[]
for i in range(m):
    a,b=map(int,input().split())
    v.append((a-1,b-1))
def dfs(x):
    check[x]=True
    for i in graph[x]:
        if not check[i]:
            dfs(i)
ans=0
for i in range(m):
    graph=[[] for i in range(n)]
    for j in range(m):
        if j!=i:
            graph[v[j][0]].append(v[j][1])
            graph[v[j][1]].append(v[j][0])
    check=[False]*n
    dfs(0)
    for j in check:
        if not j:
            ans+=1
            break
print(ans)

Solution (Python):
import sys

input = sys.stdin.readline

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

class UnionFind():
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n + 1)
    
    def root(self, x):
        if self.par[x] == x:
            return x
        self.par[x] = self.root(self.par[x])
 
        return self.par[x]
    
    def same(self, x, y):
        return self.root(x) == self.root(y)
    
    def union(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
        if self.rank[x] == self.rank[y]:
            self.rank[x] += 1
 
ans = 0
for i in range(M):
    Path = AB[:i] + AB[i+1:]
    uf = UnionFind(N)
    for x, y in Path:
        uf.union(x, y)

    count = 0
    for j in range(1, N+1):
        if uf.par[j] == j:
            count += 1
            if count >= 2:
                ans += 1
                break
    
print(ans)

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

def root(a):
    if par[a]<0:
        return a
    else:
        return root(par[a])

def size(a):
    return -par[root(a)]

def connect(a,b):
    a=root(a)
    b=root(b)
    if a==b:
        return False
    if size(a)<size(b):
        a,b=b,a
    par[a]+=par[b]
    par[b]=a
    return True

a=[]
for i in range(m):
    a.append([int(j)-1 for j in input().split()])

ans=0
for i in range(m):
    par=[-1 for i in range(n)] 
    for j in range(m):
        if j==i:
            continue
        if root(a[j][0])!=root(a[j][1]):
            connect(a[j][0],a[j][1])
    if -1*min(par)!=n:
        ans+=1
print(ans)

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

def root(a):
    if par[a]<0:
        return a
    else:
        return root(par[a])

def size(a):
    return -par[root(a)]

def connect(a,b):
    a=root(a)
    b=root(b)
    if a==b:
        return False
    if size(a)<size(b):
        a,b=b,a
    par[a]+=par[b]
    par[b]=a
    return True

a=[]
for i in range(m):
    a.append([int(j)-1 for j in input().split()])

ans=0
for i in range(m):
    par=[-1 for i in range(n)] 
    for j in range(m):
        if j==i:
            continue
        if root(a[j][0])!=root(a[j][1]):
            connect(a[j][0],a[j][1])
    if -1*min(par)!=n:
        ans+=1
print(ans)