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):
N,M=map(int,input().split())
a=[0 for i in range(M)]
b=[0 for i in range(M)]
for i in range(M):
    a[i],b[i]=map(int,input().split())
    a[i]-=1
    b[i]-=1
par=[0 for i in range(N)]
rnk=[0 for i in range(N)]
def init(n):
    for i in range(N):
        par[i]=i
        rnk[i]=0
def find(x):
    if par[x]==x:
        return x
    else:
        par[x]=find(par[x])
        return par[x]
def unite(x,y):
    x=find(x)
    y=find(y)
    if x==y:
        return
    if (rnk[x]<rnk[y]):
        par[x]=y
    else:
        par[y]=x
        if(rnk[x]==rnk[y]):
            rnk[x]+=1
def same(x,y):
    return find(x)==find(y)
ans=0
for i in range(M):
    init(N)
    for j in range(M):
        if i==j:
            continue
        unite(a[j],b[j])
    flag=0
    for j in range(1,N):
        if find(0)!=find(j):
            flag=1
            break
    if flag==1:
        ans+=1
print(ans)

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


def reach(cur, par, goal):
    if cur == goal:
        return True
    if used[cur]:
        return False
    used[cur] = True
    for e in edge[cur]:
        if e == par:
            continue
        if reach(e, cur, goal):
            used[cur] = False
            return True
    used[cur] = False
    return False


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

counter = 0
for i in range(n):
    for e in edge[i]:
        if not reach(i, e, e):
            counter += 1

print(counter // 2)

Solution (Python):
N,M=map(int,input().split())
a=[0 for i in range(M)]
b=[0 for i in range(M)]
for i in range(M):
    a[i],b[i]=map(int,input().split())
    a[i]-=1
    b[i]-=1
par=[0 for i in range(N)]
rnk=[0 for i in range(N)]
def init(n):
    for i in range(N):
        par[i]=i
        rnk[i]=0
def find(x):
    if par[x]==x:
        return x
    else:
        par[x]=find(par[x])
        return par[x]
def unite(x,y):
    x=find(x)
    y=find(y)
    if x==y:
        return
    if (rnk[x]<rnk[y]):
        par[x]=y
    else:
        par[y]=x
        if(rnk[x]==rnk[y]):
            rnk[x]+=1
def same(x,y):
    return find(x)==find(y)
ans=0
for i in range(M):
    init(N)
    for j in range(M):
        if i==j:
            continue
        unite(a[j],b[j])
    flag=0
    for j in range(N):
        for k in range(N):
            if find(j)!=find(k):
                flag=1
                break
        if flag==1:
            break
    if flag==1:
        ans+=1
print(ans)

Solution (Python):
from collections import defaultdict
n, m = map(int, input().split())
G = defaultdict(list)
s = []
for i in range(m):
    a, b = map(int, input().split())
    G[a - 1].append(b - 1)
    G[b - 1].append(a - 1)
    s.append((a - 1, b - 1))


def dfs(cur, pre, NG, k):
    global used
    used[cur] = 1
    for v in G[cur]:
        if v != pre and used[v] != 1 and (v, cur) != NG and (cur, v) != NG:
            dfs(v, cur, NG, k + 1)


num = 0
for i in range(m):
    ng = s[i]
    used = [0] * n
    used[0] = 1
    dfs(0, -1, ng, 0)
    if sum(used) == n:
        num += 1

print(m - num)

Solution (Python):
def dfs(now):
    if vis[now]:
        return 0
    vis[now]=1
    for i in range(n):
        if graph[now][i]:
            dfs(i)
n,m=map(int,input().split())
edge=[[int(i) for i in input().split()]for i in range(m)]
graph=[[0 for i in range(n)]for i in range(n)]
for i in range(m):
    graph[edge[i][0]-1][edge[i][1]-1]=1
    graph[edge[i][1]-1][edge[i][0]-1]=1
vis=[0]*n
ans=0
for i in range(m):
    graph[edge[i][0]-1][edge[i][1]-1]=0
    graph[edge[i][1]-1][edge[i][0]-1]=0
    vis=[0]*n
    dfs(0)
    connect=False
    for j in range(n):
        if vis[j]==0:
            connect=True
    if connect:
        ans+=1
    graph[edge[i][0]-1][edge[i][1]-1]=1
    graph[edge[i][1]-1][edge[i][0]-1]=1

print(ans)

Solution (Python):

n, m = map(int, input().split(" "))
a = [list(map(int, input().split(" "))) for i in range(m)]
 
a_connects = [[] for i in range(n)]
for x, y in a:
	a_connects[x-1].append(y-1)
	a_connects[y-1].append(x-1)

jkl = []
for i in range(n):
    jkl.append(1)

def ss(n): 
    jkl[n] = 0
    for x in a_connects[n]:
        if jkl[x] != 0:
            ss(x)
ass = 0            
for i in range(m):
    a_connects[a[i][0]-1].remove(a[i][1]-1)
    a_connects[a[i][1]-1].remove(a[i][0]-1)
    ss(0)
    if sum(jkl) != 0:
        ass += 1
    a_connects[a[i][0]-1].append(a[i][1]-1)
    a_connects[a[i][1]-1].append(a[i][0]-1)
    jkl = []
    for i in range(n):
        jkl.append(1)
print(ass)

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

a_connects = [[] for i in range(n)]
for x, y in a:
	a_connects[x-1].append(y-1)
	a_connects[y-1].append(x-1)



a_connect_sums = [len(connect) for connect in a_connects]



bridge_count = 0
while 1 in a_connect_sums:
	x = a_connect_sums.index(1)
	y = a_connects[x][0]
 
	a_connects[x].remove(y)
	a_connects[y].remove(x)
 
	a_connect_sums[x] -= 1
	a_connect_sums[y] -= 1
 
	bridge_count += 1
	
	
	
 
print(bridge_count)

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

a_connects = [[] for i in range(n)]
for x, y in a:
	a_connects[x-1].append(y-1)
	a_connects[y-1].append(x-1)



a_connect_sums = [len(connect) for connect in a_connects]



bridge_count = 0
while 1 in a_connect_sums:
	x = a_connect_sums.index(1)
	y = a_connects[x][0]
 
	a_connects[x].remove(y)
	a_connects[y].remove(x)
 
	a_connect_sums[x] -= 1
	a_connect_sums[y] -= 1
 
	bridge_count += 1
	
	
	
 
print(bridge_count)

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


visited = [False]*n
aa = []
bb = []
edge = []
for i in range(51):
    edge.append([False]*51)
"""
edge = [[False]*7]*7
"""

for _ in range(m):
    a,b = map(int,input().split())
    a -= 1
    b -= 1
    aa.append(a)
    bb.append(b)
    edge[a][b] = True
    edge[b][a] = True
    """
    for l in edge:
        print(l)
    print('')
    """

def dfs(vertex):
    visited[vertex] = True
    for i in range(n):
        if edge[vertex][i] and not visited[i]:
            
            dfs(i)

res = 0
for i in range(m):
    visited = [False]*n
    edge[aa[i]][bb[i]] = False
    edge[bb[i]][aa[i]] = False
    dfs(0)
    if not visited==[True]*n:
        res += 1
    
    edge[aa[i]][bb[i]] = True
    edge[bb[i]][aa[i]] = True

print(res)

Solution (Python):
class UFT(object):
    def __init__(self,N):
        self.par={i:i for i in range(1,N+1)}
        self.h={i:0 for i in range(1,N+1)}
    def find(self,n):
        if self.par[n]==n:
            return n
        else:
            self.par[n]=self.find(self.par[n])
            return self.par[n]
    def unite(self,a,b):
        a=self.find(a)
        b=self.find(b)
        if self.h[a]>self.h[b]:
            self.par[b]=a
        else:
            self.par[a]=b
            self.h[a]+=1
    def issame(self,a,b):
        return self.find(a)==self.find(b)

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

for i in range(m):
  obj=UFT(n)
  for (j,k) in enumerate(l):
    if i!=j:
      a,b=k
      obj.unite(a,b)
  a,b=l[i]
  if not obj.issame(a,b):s+=1

print(s)

Solution (Python):
from heapq import heappush, heappop

def dijkstra(graph:list, node:int, start:int) -> list:
    
    INF = float("inf")
    dist = [INF]*node
    
    
    dist[start] = 0
    heap = [(0,start)]
    
    
    while heap:
        cost, cur_node = heappop(heap)
        
        for nex_cost, nex_node in graph[cur_node]:
            dist_cand = dist[cur_node] + nex_cost
            if dist_cand < dist[nex_node]:
                dist[nex_node] = dist_cand
                heappush(heap, (dist[nex_node], nex_node))
    
    return dist


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

for a,b in AB:
    a -= 1
    b -= 1
    adj_list[a].append((1,b))
    adj_list[b].append((1,a))

INF = float("inf")
ans = 0


for a,b in AB:
    a -= 1
    b -= 1
    
    adj_list[a].remove((1,b))
    adj_list[b].remove((1,a))
    
    dist = dijkstra(adj_list, N, 0)
    
    if INF in dist:
        ans += 1
        
    adj_list[a].append((1,b))
    adj_list[b].append((1,a))
    

print(ans)

Solution (Python):
from collections import defaultdict
import sys,heapq,bisect,math,itertools,string,queue,datetime
sys.setrecursionlimit(10**8)
INF = float('inf')
mod = 10**9+7
eps = 10**-7
AtoZ = [chr(i) for i in range(65,65+26)]
atoz = [chr(i) for i in range(97,97+26)]

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


def Find(x):	
	global table

	if table[x] == x:
		return x
	else:
		table[x] = Find(table[x])	
		return table[x]

def Unite(x,y):	
	x = Find(x)
	y = Find(y)

	if x == y:
		return

	if rank[x] > rank[y]:
		table[y] = x
	else:
		table[x] = y
		if rank[x] == rank[y]:
			rank[y] += 1

def Check(x,y):
	if Find(x) == Find(y):
		return True
	else:
		return False

N,M = inpl()

lines = [inpl() for i in range(M)]
ans = 0
for j in range(M):
	table = [_ for _ in range(N+1)]
	rank  = [1 for _ in range(N+1)]
	for i in range(M):
		if i == j:
			continue
		x,y = lines[i]
		Unite(x,y)
	x,y = lines[j]

	if not Check(x,y):
		ans += 1

print(ans)

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

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

def isConnected(a, b):
    used = [0] * N
    def dfs(pos, pre):
        if used[pos]:
            return
        
        used[pos] = 1
        for to in range(N):
            if (pos == a and to == b) or (pos == b and to == a) or (G[pos][to] == 0):
                continue
            dfs(to, pos)
    dfs(0, -1)
    return used.count(1) != N

ans = 0
for a in range(N):
    for b in range(a+1, N):
        if G[a][b] == 0:
            continue
        ans = ans + isConnected(a, b)
    
print (ans)

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

a_connects = [[] for i in range(n)]
for x, y in a:
	a_connects[x-1].append(y-1)
	a_connects[y-1].append(x-1)

a_connect_sums = [len(connect) for connect in a_connects]
bridge_count = 0
while 1 in a_connect_sums:
	x = a_connect_sums.index(1)
	y = a_connects[x][0]

	a_connects[x].remove(y)
	a_connects[y].remove(x)

	a_connect_sums[x] -= 1
	a_connect_sums[y] -= 1

	bridge_count += 1

print(bridge_count)

Solution (Python):


class UnionFind:
    def __init__(self, n):
    
        self.parent = [i for i in range(n + 1)]
    
        self.rank = [0] * (n + 1)
    
    def find(self, x):
    
        if self.parent[x] == x:
            return x
        else:
    
            self.parent[x] = self.find(self.parent[x])
            return self.find(self.parent[x])
    
    def same_check(self, x, y):
        return self.find(x) == self.find(y)
    
    def unite(self, x, y):
    
        x = self.find(x)
        y = self.find(y)
    
        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
    
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

def main():

    n, m = map(int, input().split())
    es = []

    for _ in range(m):
        a, b = map(int, input().split())
        es.append((a, b))
        
    ans = 0
    for i in range(m):
        u = UnionFind(n)
        for j, e in enumerate(es):
            if j != i:
                a, b = e
                u.unite(a, b)
        a, b = es[i]
        if not u.same_check(a, b):
            ans += 1
    
    print(ans)
        
if __name__ == '__main__':
    main()

Solution (Python):
N, M = map( int, input().split())
V = [set([]) for _ in range(N)]
E = []
for i in range(M):
    a, b = map(int, input().split())
    E.append([a-1,b-1])
    V[a-1].add(b-1)
    V[b-1].add(a-1)
ans = 0
def conn(a,b,V):
    TV = [ False for _ in range(N)]
    TV[a] = True
    S = []
    for v in V[a]:
        if v != b:
            S.append(v)
    while len(S) != 0:
        c = S.pop()
        for w in V[c]:
            if TV[w] == False:
                TV[w] = True
                S.append(w)
    return TV
for e in E:
    a, b = e[0], e[1]
    comp = conn(a,b,V)
    if comp[b] == False:
        ans += 1
print(ans)

Solution (Python):
'''
ABC 075
https://www.youtube.com/watch?v=VJntQuR2zNI

'''
def inpl(): return input().split()
def arr(r, c): return [[False for x in range(c)] for y in range(r)]

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

if __name__ == '__main__':
    n, m = map(int, inpl())
    M = [list(map(int, inpl())) for _ in range(m)]

    ans = 0
    for e in range(m):
        graph = arr(n, n)
        for i in range(m):
            if i == e:
                continue
            a, b = M[i]
            
            
            graph[a - 1][b - 1] = True
            graph[b - 1][a - 1] = True

        vis = [False for _ in range(n)]
        dfs(0)
        
        connected = True
        for i in range(n):
            if not vis[i]:
                connected = False
                break
        if not connected:
            ans += 1
    print(ans)

Solution (Python):
def bfs(branch,n):
	arrival = [0 for i in range(n+1)]
	q = [1]
	arrival[q[0]]=1
	while len(q) >= 1:
		for k in range(len(branch[q[0]])):
			if arrival[branch[q[0]][k]] == 0:
				arrival[branch[q[0]][k]] = arrival[q[0]] + 1
				q.append(branch[q[0]][k])
		q.pop(0)
	return arrival

n,m = map(int,input().split())
branch = dict()
for i in range(1,n+1):
    branch[i] = []
pair = []
for i in range(m):
    a,b = map(int,input().split())
    pair.append([a,b])
    branch[a].append(b)
    branch[b].append(a)
counter = 0

for i in range(m):
    branch[pair[i][0]].remove(pair[i][1])
    branch[pair[i][1]].remove(pair[i][0])
    arrival = bfs(branch,n)
    check = True
    for k in range(1,n+1):
        if arrival[k] == 0:
            check = False
    if check:
        counter += 1
    branch[pair[i][0]].append(pair[i][1])
    branch[pair[i][1]].append(pair[i][0])
print(m-counter)

Solution (Python):
class DFS:
    def __init__(self, N):
        self.N = N
        self.visited = [False for i in range(N)]
        self.graph = [[False for i in range(N)] for j in range(N)]

    def dfs(self, v):
        self.visited[v] = True
        for i in range(self.N):
            if (self.graph[v][i] == False):
                continue
            if (self.visited[i]):
                continue
            self.dfs(i)


N,M = map(int, input().split())
a = []
b = []
dfs = DFS(N)

for i in range(M):
    x,y = map(int, input().split())
    a.append(x-1)
    b.append(y-1)
    dfs.graph[a[i]][b[i]] = True
    dfs.graph[b[i]][a[i]] = True
ans = 0
for i in range(M):

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

Solution (Python):
N, M = map(int, input().split())
f, t = [], []

for i in range(M) :
    a, b = map(int, input().split())
    
    f.append(a)
    t.append(b)
    
def get_root(idx) :
    if idx == u[idx] :
        return idx
    else :
        u[idx] = get_root(u[idx])
        return u[idx]
    
def union(a, b) :
    if get_root(a) <= get_root(b) :
        u[get_root(b)] = get_root(a)
    else :
        u[get_root(a)] = get_root(b)
cnt = 0 

for i in range(M) :
    u = [x for x in range(N)]
    
    for j in range(M) :
        if i != j :
            union(f[j] - 1, t[j] - 1)
    
    u_sets = set()
    for j in range(N) :
        u_sets.add(get_root(j))
        
    
    if len(list(u_sets)) != 1 :
        cnt += 1
        
print(cnt)

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

a = []
for i in range(m):
    a.append(list(map(int,input().split())))

b = [[0 for i in range(n)] for j in range(n)]

for i in a:
    b[i[1]-1][i[0]-1] = 1
    b[i[0]-1][i[1]-1] = 1
c = [sum(b[i]) for i in range(n)]
ans = 0
while 1 in c:
    d = c.index(1)
    e = b[d].index(1)
    b[e][d] = 0
    b[d][e] = 0
    c = [sum(b[i]) for i in range(n)]
    ans += 1
print(ans)

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

used_v = [False for i in range(n+1)]
used_e = [[False for i in range(n+1)] for i in range(n+1)]
ord_ = [float("INF") for i in range(n+1)]
lowlink = [float("INF") for i in range(n+1)]

def dfs(v, k):
  used_v[v] = True
  ord_[v], lowlink[v] = k, k
  k += 1
  for to in graph[v]:
    if not used_v[to]:
      used_e[v][to] = True
      dfs(to, k)
      lowlink[v] = min(lowlink[v], lowlink[to])
    elif not used_e[to][v]:
      lowlink[v] = min(lowlink[v], ord_[to])

dfs(1, 0)
ans = 0
for a, b in e:
  if ord_[a]<lowlink[b] or ord_[b]<lowlink[a]:
    ans+=1
print(ans)

Solution (Python):
class UnionFind():
    def __init__(self,size):
        self.table = [-1 for _  in range(size)]

    def find(self,x):
        while self.table[x] >= 0:
            x = self.table[x]
        return x

    def union(self,x,y):
        s1 = self.find(x)
        s2 = self.find(y)
        if s1 != s2:
            if self.table[s1] != self.table[s2]:
                if self.table[s1] < self.table[s2]:
                    self.table[s2] = s1
                else:
                    self.table[s1] = s2
            else:
                self.table[s1] += -1
                self.table[s2] = s1
        return

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

edges = [map(int,raw_input().split()) for i in range(m)]

ans = 0

for i in range(m):
	uf = UnionFind(n)
	for j in range(m):
		if i != j:
			uf.union(edges[j][0]-1,edges[j][1]-1)

	c = 0
	for j in range(n):
		if j == uf.find(j):
			c += 1

	if c > 1 :
		ans += 1

print ans

Solution (Python):
n,m = map(int,input().split())
ft = [[int(i) -1 for i in input().split()] for _ in range(m)]
def dfs(f,n):

    visited[n] = True


    for value in renketu[n]:
        if value == f:
            continue
        if visited[value] == True:
            continue
        
        dfs(n,value)

    return
    

total = 0

for i in range(m):

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

    tmp = ft.pop(i)

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

    for value in ft:
        f,t = value
        renketu[f].append(t)
        renketu[t].append(f)

    dfs(0,0)
    
    
    if visited.count(True) != n:
        total += 1
    ft.insert(i,tmp)

print(total)

Solution (Python):


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


a = [0] * 50
b = [0] * 50

graph = [[False for i in range(50)] for j in range(50)]

visited = [False] * N


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


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

ans = 0

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

print(ans)

Solution (Python):


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


a = [0] * 50
b = [0] * 50

graph = [[False for i in range(50)] for j in range(50)]

visited = [False] * N


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


def dfs(v):
    
    global graph
    global visited
    
    if visited[v]:
        return
    
    visited[v] = True
    for v2 in range(N):
        
        if graph[v][v2]:
            
            dfs(v2)

ans = 0

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

print(ans)

Solution (Python):
n=input().split()
rap=int(n[0])
sap=int(n[1])
map=[]
hap=[[] for i in range(1,rap+1)]
count=0
visited=[0 for i in range(1,1+rap)]
for i in range(sap):
    knight=input().split()
    morn=int(knight[0])-1
    after=int(knight[1])-1
    hap[morn].append(after)
    hap[after].append(morn)
    map.append([morn,after])
def dfs(u):
    visited[u]=1
    for v in king[u]:
        if visited[v]==0:
            dfs(v)
for j in range(sap):
    king=hap.copy()
    visited=[0 for i in range(1,rap+1)]
    king[map[j][0]].remove(map[j][1])
    king[map[j][1]].remove(map[j][0])
    dfs(map[j][0])
    king[map[j][0]].append(map[j][1])
    king[map[j][1]].append(map[j][0])
    sum=0
    for i in range(len(visited)):
        sum+=visited[i]
    if sum<rap:
        count+=1
print(count)

Solution (Python):
x=input().split()
n=int(x[0])
m=int(x[1])
adj=[[] for i in range(n)]
inp=[[0]*2 for i in range(m)]
count=0
visited=[False for i in range(n)]
def dfs(u):
    visited[u]=True
    for v in adj[u]:
        if not visited[v-1]:
            dfs(v-1)
for i in range(m):
    x=input().split()
    a=int(x[0])
    b=int(x[1])
    inp[i][0]=a
    inp[i][1]=b
ind=0
for i in inp:
    visited=[False for ii in range(n)]
    adj=[[] for iii in range(n)]
    inp[ind]=[]
    for j in inp:
        if j!=[]:
            adj[j[0]-1].append(j[1])
            adj[j[1]-1].append(j[0])
    
    dfs(0)
    for k in visited:
        if k==False:
            count+=1
            break
    inp[ind]=i
    ind+=1
print(count)

Solution (Python):
N,M = [int(x) for x in str(input()).split()]
E=[]
for i in range(M):
  E.append([int(x) for x in str(input()).split()])


def dfs(u):
  visited[u]=True
  for j in adj[u]:
    if visited[j]==False:
      dfs(j)

count=0
for i in range(M):
  P=E[:i]+E[i+1:]
  visited=[False for x in range(0,N+1)]
  adj=[[0] for k in range(0,N+1)]
  for j in range(1,N+1):
    r=[]
    for l in P:
      if l[0]==j:
        r.append(l[1])
      elif l[1]==j:
        r.append(l[0])
    adj[j]=r
  dfs(1)
  if sum(visited)!=N:
    count+=1
print(count)

Solution (Python):
N,M = map(int,input().split())
es = [tuple(map(lambda x:int(x)-1,input().split())) for i in range(M)]
gr = [[] for i in range(N)]
for i,(a,b) in enumerate(es):
    gr[a].append((b,i))
    gr[b].append((a,i))

ans = 0
for i in range(M):
    visited = [0] * N
    stack = [0]
    while stack:
        v = stack.pop()
        visited[v] = 1
        for to,e in gr[v]:
            if visited[to]: continue
            if i==e: continue
            stack.append(to)
    if sum(visited) < N:
        ans += 1
print(ans)

Solution (Python):
from collections import deque
N,M=map(int,input().split())
links = {}
linkList = []
for i in range(M):
    a,b=map(int,input().split())
    linkList.append((a,b))
    if a not in links:
        links[a] = [b]
    else:
        links[a].append(b)
    if b not in links:
        links[b] = [a]
    else:
        links[b].append(a)
ans = 0
for a,b in linkList:
    links[a].remove(b)
    links[b].remove(a)
    visited = set()
    queue = deque()
    queue.appendleft(1)
    while queue:
        v = queue.pop()
        for w in links[v]:
            if w not in visited:
                queue.appendleft(w)
                visited.add(w)
    if len(visited) != N:
        ans += 1
    links[a].append(b)
    links[b].append(a)
print(ans)

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

def root(val):
    if parent[val]==val:
        return val
    else:
        parent[val]=root(parent[val])
        return parent[val]

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

def unite(x,y):
    xr=root(x)
    yr=root(y)
    if xr==yr :return
    if rank[xr]<rank[yr]:
        parent[xr]=yr
    else:
        parent[yr]=xr
        if rank[xr]==rank[yr]:
            rank[xr]+=1
ct=0
for i in range(M):
    parent=list(range(N))
    rank = [0]*N
    for a,b in (ab[:i]+ab[i+1:]):
        unite(a-1,b-1)
    for j in range(1,N):
        if not same(0,j):
            ct+=1
            break
print(ct)

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

from pprint import pprint

l=[[False for _ in range(n)] for _ in range(n)]
v=[True for _ in range(n)]
for a,b in ab:
    l[b-1][a-1], l[a-1][b-1]=True,True
def dfs(x,t,v,j,m,n):
    j+=1
    if j<n+m:
        v[x]=False
        for i in range(1,n):
            if v[i]:
                if t[x][i]:
                    dfs(i,t,v,j,m,n)
import copy

ans=0
for i in range(m):
    j=0
    t=copy.deepcopy(l)
    t[ab[i][1]-1][ab[i][0]-1],t[ab[i][0]-1][ab[i][1]-1]=False,False
    v=[True for _ in range(n)]
    dfs(0, t, v, j, m,n)
        
    z=False
    for x in v:
        if x:
            z=True
    if z:
        ans+=1
print(ans)

Solution (Python):

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

adj_matrix = {} 
for i in range(1, N + 1):
    adj_lst = []
    for j in range(M):
        if edge_lst[j][0] == i:
            adj_lst.append(edge_lst[j][1])
        if edge_lst[j][1] == i:
            adj_lst.append(edge_lst[j][0])
    adj_matrix[i] = adj_lst







def dfs_bridge(graph, root, next, count, low, order, bridges): 
    count += 1
    order[next] = count
    low[next] = order[next]

    for w in graph[next]: 
        if order[w] == -1: 
            dfs_bridge(graph, next, w, count, low, order, bridges)

            low[next] = min(low[next], low[w])
            if low[w] == order[w]: 
                bridges.append((next, w))
        elif w != root: 
            low[next] = min(low[next], order[w])

def get_bridges(graph):
    bridges = []
    count = 0
    low = {n: -1 for n in graph.keys()}
    order = low.copy()

    for n in graph.keys():
        dfs_bridge(graph, n, n, count, low, order, bridges)
    
    return(bridges) 
            
ans = get_bridges(adj_matrix)
print(len(ans))

Solution (Python):
from collections import defaultdict
import queue

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

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

renketu = 0
for m in range(M): 
    D = defaultdict(list) 
    for l in L[:m]+L[m+1:]:
        a,b = l[0],l[1]
        D[a].append(b)
        D[b].append(a)
    Q = queue.Queue()
    Q.put(L[0][0])
    walked = [L[0][0]]
    
    while(True):
        now = Q.get()
        for d in D[now]:
            if d not in walked:
                Q.put(d)
                walked.append(d)
        
        if len(walked)==N:break
        if Q.empty():break
    if len(walked)==N:
        
        renketu+=1
    
        
print(M-renketu)

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

    def find(self, x):
        while 1:
            i = self.table[x]
            if i < 0:
                return x
            x = i

    def union(self,x,y):
        s1 = self.find(x)
        s2 = self.find(y)
        if s1 == s2:
            return
        d = self.table[s1] - self.table[s2]
        if d < 0:
            self.table[s2] = s1
        elif d > 0:
            self.table[s1] = s2
        else:
            self.table[s1] += -1
            self.table[s2] = s1

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

result = 0

for a1, b1 in ab:
    uf = UnionFind(N + 1)
    for a, b in ab:
        if (a, b) == (a1, b1):
            continue
        uf.union(a, b)
    rs = set([])
    for i in range(1, N + 1):
        rs.add(uf.find(i))
    if len(rs) > 1:
        result += 1

print(result)

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

    def find(self, x):
        while self.table[x] >= 0:
            x = self.table[x]
        return x

    def union(self,x,y):
        s1 = self.find(x)
        s2 = self.find(y)
        if s1 != s2:
            if self.table[s1] != self.table[s2]:
                if self.table[s1] < self.table[s2]:
                    self.table[s2] = s1
                else:
                    self.table[s1] = s2
            else:
                self.table[s1] += -1
                self.table[s2] = s1
        return

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

result = 0

for a1, b1 in ab:
    uf = UnionFind(N + 1)
    for a, b in ab:
        if (a, b) == (a1, b1):
            continue
        uf.union(a, b)
    rs = set([])
    for i in range(1, N + 1):
        rs.add(uf.find(i))
    if len(rs) > 1:
        result += 1

print(result)

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

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

    def union(self,x,y):
        px = self.find(x)
        py = self.find(y)
        if px == py:
            return 
        if self.rank[px]<self.rank[py]:
            self.par[px]=py
        else:
            self.par[py]=px
        if self.rank[px]==self.rank[py]:
            self.rank[px] +=1
    
    def connect(self,x,y):
        return self.find(x)==self.find(y)

N,M=map(int,input().split())
table=[]
for i in range(M):
    a,b=map(int,input().split())
    table.append([a-1,b-1])
ans =0
for i in range(M):
    K=Unionfindtree(N)
    for j in range(M):
        if i==j:
            continue
        a,b=table[j]
        K.union(a,b)
    flag=False
    for k in range(1,N):
        if not K.connect(0,k):
            flag=True
    if flag:
        ans+=1
print(ans)