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):
def dfs(u, visited, g):
	visited[u] = True
	for v in g[u]:
		if visited[v] == True:
			continue
		dfs(v, visited, g)

def resolve():
	n, m = map(int, input().split())

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

	for i in range(m):
		visited = [False]*n
		g = [[] for _ in range(n)]
		e = edges[:i] + edges[i+1:]
		for i in range(m-1):
			g[e[i][0]].append(e[i][1])
			g[e[i][1]].append(e[i][0])

		dfs(0, visited, g)
		if len(visited) != visited.count(True):
			ans += 1

	print(ans)
resolve()

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

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

Ms = [list(map(int, input().split())) for _ in range(M)]
ans = 0
for i in range(M):
    uf = UnionFind(N)
    for j in range(M):
        if i==j:
            continue
        a, b = Ms[j]
        uf.union(a-1, b-1)
    if uf.group_count()!=1:
        ans += 1
print(ans)

Solution (Python):
class UnionFind:
    def __init__(self, n):
        self.nodes = n
        self.parents = [i for i in range(n)]
        self.sizes = [1] * n
        self.rank = [0] * n

    def find(self, i):
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) 
            return self.parents[i]

    def unite(self, i, j):
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
    def same(self, i, j):
        return self.find(i)==self.find(j)

    def get_parents(self):
        for n in range(self.nodes): 
            self.find(n)
        return self.parents

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

ans = 0
for i in range(M):
    uf = UnionFind(N)
    for j in range(M):
        if (i==j):
            continue
        uf.unite(*adj[j])
    
    if len(set(uf.get_parents()))!=1: 
        ans += 1
print (ans)

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

    def find(self, i):
        if self.parents[i] == i:
            return i
        else:
            self.parents[i] = self.find(self.parents[i]) 
            return self.parents[i]

    def unite(self, i, j):
        pi = self.find(i)
        pj = self.find(j)
        if pi != pj:
            if self.rank[pi] < self.rank[pj]:
                self.sizes[pj] += self.sizes[pi]
                self.parents[pi] = pj
            else:
                self.sizes[pi] += self.sizes[pj]
                self.parents[pj] = pi
                if self.rank[pi] == self.rank[pj]:
                    self.rank[pi] += 1
    def same(self, i, j):
        return self.find(i)==self.find(j)














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

ans = 0
for i in range(M):
    uf = UnionFind(N)
    for j in range(M):
        if (i==j):
            continue
        uf.unite(*adj[j])
    
    for n in range(N):
        uf.find(n)
    
    if len(set(uf.parents))!=1:
        ans += 1
    
print (ans)

Solution (Python):
import sys
import heapq
import re
from itertools import permutations
from bisect import bisect_left, bisect_right
from collections import Counter, deque
from fractions import gcd
from math import factorial, sqrt, ceil
from functools import lru_cache, reduce
INF = 1 << 60
MOD = 1000000007
sys.setrecursionlimit(10 ** 7)


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



def warshall_floyd(d):
    
    for k in range(n):
        for i in range(n):
            for j in range(n):
                d[i][j] = min(d[i][j],d[i][k] + d[k][j])
    return d



def dijkstra_heap(s, edge, n):
    
    d = [10**20] * n
    used = [True] * n 
    d[s] = 0
    used[s] = False
    edgelist = []
    for a,b in edge[s]:
        heapq.heappush(edgelist,a*(10**6)+b)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        
        if not used[minedge%(10**6)]:
            continue
        v = minedge%(10**6)
        d[v] = minedge//(10**6)
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,(e[0]+d[v])*(10**6)+e[1])
    return d


def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            arr.append([i, cnt])

    if temp!=1:
        arr.append([temp, 1])

    if arr==[]:
        arr.append([n, 1])

    return arr


def lcm(x, y):
    return (x * y) // gcd(x, y)


def lcm_list(numbers):
    return reduce(lcm, numbers, 1)


def gcd_list(numbers):
    return reduce(gcd, numbers)


def is_prime(n):
    if n <= 1:
        return False
    p = 2
    while True:
        if p ** 2 > n:
            break
        if n % p == 0:
            return False
        p += 1
    return True



def eratosthenes(limit):
    A = [i for i in range(2, limit+1)]
    P = []

    while True:
        prime = min(A)
        
        if prime > sqrt(limit):
            break
            
        P.append(prime)
            
        i = 0
        while i < len(A):
            if A[i] % prime == 0:
                A.pop(i)
                continue
            i += 1
            
    for a in A:
        P.append(a)
            
    return P


def permutation_with_duplicates(L):

    if L == []:
        return [[]]

    else:
        ret = []

        
        S = sorted(set(L))

        for i in S:

            data = L[:]
            data.remove(i)

            for j in permutation_with_duplicates(data):
                ret.append([i] + j)

        return ret




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


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

ans = 0


for i in range(m):
    queue = deque([])
    visited = [0 for i in range(n)]
    queue.append(0)
    while queue:
        now = queue.popleft()
        if visited[now] == 1:
            continue
        visited[now] = 1
        for j in x[now]:
            if j[0] != i:
                queue.append(j[1]) 
        
            
    if sum(visited) != n:
        ans += 1
    
        
print(ans)

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

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

ab += [[b,a] for a,b in ab]


abi = [[] for _ in range(n+1)]
for i,(a,b) in enumerate(ab):
    abi[a].append(b)
    abi[b].append(a)



import sys
sys.setrecursionlimit(4100000)

from collections import deque



def dfs(i):
    visitted.append(i)
    flg = False
    for x in abi[i]:
        if x not in visitted and (i,x) != blocked and (x,i) != blocked:
            dfs(x)
            flg = True
    return len(visitted)==n

ret = 0
for i in range(m):
    blocked = (ab[i][0],ab[i][1])
    visitted = deque([])
    if not dfs(1):
        ret+=1

print(ret)

Solution (Python):

from collections import deque

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


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



cnt = 0
for edge_to_remove in E:
    
    i, j = edge_to_remove
    G[i].remove(j)
    G[j].remove(i)

    
    seen = set()
    todo = deque()
    
    todo.append(0)
    seen.add(0)
    while todo:
        here = todo.pop()
        for neighbor in G[here]:
            if neighbor not in seen:
                seen.add(neighbor)
                todo.append(neighbor)
    
    
    if len(seen) < N:
        cnt += 1

    
    G[i].append(j)
    G[j].append(i)
print(cnt)

Solution (Python):

from collections import deque

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


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



cnt = 0
for edge_to_remove in E:
    
    i, j = edge_to_remove
    G[i].remove(j)
    G[j].remove(i)

    
    seen = [False] * N
    todo = deque()
    
    todo.append(0)
    seen[0] = True
    seen_nodes_num = 0
    while todo:
        here = todo.pop()
        seen_nodes_num += 1
        for neighbor in G[here]:
            if seen[neighbor] == False:
                seen[neighbor] = True
                todo.append(neighbor)
    
    
    if seen_nodes_num != N:
        cnt += 1

    
    G[i].append(j)
    G[j].append(i)
print(cnt)

Solution (Python):

from collections import deque

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


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



cnt = 0
for edge_to_remove in E:
    
    i, j = edge_to_remove
    G[i].remove(j)
    G[j].remove(i)

    
    seen = [False] * N
    todo = deque()
    
    todo.append(0)
    seen[0] = True
    seen_nodes_num = 0
    while todo:
        here = todo.popleft()
        seen_nodes_num += 1
        for neighbor in G[here]:
            if seen[neighbor] == False:
                seen[neighbor] = True
                todo.append(neighbor)
    
    
    if seen_nodes_num != N:
        cnt += 1

    
    G[i].append(j)
    G[j].append(i)
print(cnt)

Solution (Python):

from collections import deque

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


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



cnt = 0
for edge_to_remove in E:
    
    i, j = edge_to_remove
    G[i].remove(j)
    G[j].remove(i)

    
    seen = [False] * N
    todo = deque()
    
    todo.append(0)
    seen[0] = True
    seen_nodes_num = 0
    while todo:
        here = todo.pop()
        seen_nodes_num += 1
        for neighbor in G[here]:
            if seen[neighbor] == False:
                seen[neighbor] = True
                todo.append(neighbor)
    
    
    if seen_nodes_num != N:
        cnt += 1

    
    G[i].append(j)
    G[j].append(i)
print(cnt)

Solution (Python):

from collections import deque

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


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



cnt = 0
for edge_to_remove in E:
    
    i, j = edge_to_remove
    G[i].remove(j)
    G[j].remove(i)

    
    seen = [False] * N
    todo = deque()
    
    todo.append(0)
    seen[0] = True
    while todo:
        
        
        here = todo.popleft()
        
        for neighbor in G[here]:
            if seen[neighbor] == False:
                seen[neighbor] = True
                todo.append(neighbor)
    
    
    if False in seen:
        cnt += 1

    
    G[i].append(j)
    G[j].append(i)
print(cnt)

Solution (Python):

from collections import deque

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


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



cnt = 0
for edge_to_remove in E:
    
    i, j = edge_to_remove
    G[i].remove(j)
    G[j].remove(i)

    
    seen = [False] * N
    todo = deque()
    
    todo.append(0)
    seen[0] = True
    while todo:
        here = todo.pop()
        for neighbor in G[here]:
            if seen[neighbor] == False:
                seen[neighbor] = True
                todo.append(neighbor)
    
    
    if False in seen:
        cnt += 1

    
    G[i].append(j)
    G[j].append(i)
print(cnt)

Solution (Python):
from collections import deque


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


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


cnt = 0
for edge_to_remove in E:
    
    i, j = edge_to_remove
    G[i].remove(j)
    G[j].remove(i)

    
    seen = [False] * N
    todo = deque()
    todo.append(0)
    seen[0] = True
    while todo:
        here = todo.pop()
        for neighbor in G[here]:
            if seen[neighbor] == False:
                seen[neighbor] = True
                todo.append(neighbor)
    
    if False in seen:
        cnt += 1
    
    G[i].append(j)
    G[j].append(i)
print(cnt)

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 same(self, x, y):
        return self.find(x) == self.find(y)

    
    def count_group(self):
        return len({self.find(x) for x in range(n)})

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

cnt = 0


for i in range(m):
    
    U = UnionFind(n)
    
    for j in range(m):
        if i == j:
            continue
        a, b = lista[j]
        U.union(a - 1, b - 1)
    
    if U.count_group() > 1:
        cnt += 1
print(cnt)

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

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

Nodes = [{} for i in range(N)]
for pair in pairs:
    a, b = pair
    a -= 1
    b -= 1
    Nodes[a][b] = 1
    Nodes[b][a] = 1


def dfs(i):
    isFound[i] = True
    for neighbor in tmp_Nodes[i]:
        if isFound[neighbor] == False:
            dfs(neighbor)


count = 0
for skip in range(M):
    tmp_Nodes = copy.deepcopy(Nodes)
    a, b = pairs[skip]
    a -= 1
    b -= 1
    tmp_Nodes[a].pop(b)
    tmp_Nodes[b].pop(a)

    isFound = [False for _ in range(N)]
    dfs(0)
    
    for v in isFound:
        if v == False:
            count += 1
            break

print(count)

Solution (Python):
from sys import stdin


def dfs(g, v, visited):
    visited[v] = True

    for v2 in range(len(visited)):
        if not g[v][v2]:
            continue
        if visited[v2]:
            continue
        dfs(g, v2, visited)


def main():
    n, m = map(int, stdin.readline().split())
    ab = [list(map(int, stdin.readline().split())) for _ in range(m)]
    g = [[False] * n for _ in range(n)]
    for a, b in ab:
        g[a - 1][b - 1] = True
        g[b - 1][a - 1] = True

    ans = 0

    for i in range(m):
        visited = [False for _ in range(n)]
        a, b = ab[i]
        g[a - 1][b - 1] = False
        g[b - 1][a - 1] = False

        dfs(g, 0, visited)

        check = False
        for v in visited:
            if not v:
                check = True
        if check:
            ans += 1

        g[a - 1][b - 1] = True
        g[b - 1][a - 1] = True

    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
from sys import setrecursionlimit

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

    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 check(self, x, y):
        
        return self.find(x) == self.find(y)


    def union(self, x, y):
        
        x = self.find(x)
        y = self.find(y)
        if x == y:return
        
        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 count_group(self):
        return len({self.find(x) for x in range(1, n + 1)})

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

cnt = 0
for i in range(m):
    uf = UnionFind(n)
    for j in range(m):
        if i == j:continue
        a, b = ab[j]
        uf.union(a, b)

    if uf.count_group() > 1:cnt += 1
print(cnt)

Solution (Python):
import sys

readline = sys.stdin.readline

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.rank = [0] * 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.rank[x] < self.rank[y]:
            self.parents[x] = y
        else:
            self.parents[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

def main():
    N, M = map(int, readline().split())
    nodelist = []
    for _ in range(M):
        a, b = map(int, readline().split())
        a -= 1; b -= 1
        nodelist.append([a, b])

    ans = 0
    for i in range(M):
        uf = UnionFind(N)
        for j, node in enumerate(nodelist):
            if j == i:
                continue
            uf.union(node[0], node[1])
        parent = []
        for k in range(N):
            parent.append(uf.find(k))
        if len(set(parent)) > 1:
            ans += 1
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
import sys
read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines

class UnionFind:
    def __init__(self, n):
        
        self.par = [i for i in range(n+1)]
        
        self.size = [1] * (n+1)
    
    
    def find(self, x):
        
        if self.par[x] == x:
            return x
        
        else:
            
            self.par[x] = self.find(self.par[x])
            return self.find(self.par[x])
  
    
    def unite(self, x, y):
        
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        
        if self.size[x] < self.size[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
           
    
    def is_same(self, x, y):
        return self.find(x) == self.find(y)
    
    
    def get_size(self, x):
        return self.size[self.find(x)]
    
    
    def group_sum(self):
        c = 0
        for i in range(len(self.par)):
            if self.find(i) == i:
                c += 1
        return c
    

def main():
    N,M,*ab = map(int, read().split())

    E = []
    for a, b in zip(*[iter(ab)]*2):
        E.append((a, b))

    ans = 0
    for i in range(M):
        
        uf = UnionFind(N)
        for j, (a, b) in enumerate(E):
            if j == i:
                continue
            uf.unite(a, b)
        if uf.get_size(E[i][0]) + uf.get_size(E[i][1]) == N:
            ans += 1
    
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
import sys
import copy

readline = sys.stdin.readline

def dfs(p, x):
    global graphtmp, check
    to = graphtmp[x]
    check[x] = 1
    for t in to:
        if p == t or check[t] == 1:
            continue
        dfs(x, t)

def main():
    global graphtmp, check
    N, M = map(int, readline().split())
    graph = [[] for _ in range(N)]
    nodelist = []
    for _ in range(M):
        a, b = map(int, readline().split())
        a -= 1; b-= 1
        nodelist.append([a, b])
        graph[a].append(b)
        graph[b].append(a)
    
    ans = 0
    for nodetmp in nodelist:
        check = [0]*N
        graphtmp = copy.deepcopy(graph)
        graphtmp[nodetmp[0]].remove(nodetmp[1])
        graphtmp[nodetmp[1]].remove(nodetmp[0])
        dfs(-1, 0)
        if 0 in check:
            ans += 1
    print(ans)


if __name__ == "__main__":
    main()

Solution (Python):
N,M = list(map(int,input().split()))
from collections import deque
A = [[] for i in range(N)]
line_list = []
ans = 0
for i in range(M):
    B,C = map(int,input().split())
    B -=1
    C -=1
    A[B].append(C)
    A[C].append(B)
    line_list.append([B,C])
for i in range(M):
    B = 0
    C = line_list[i]
    start = C[0]
    end = C[1]
    que = deque(A[start])
    que.remove(end)
    after = deque([start])
    while que != deque([]):
        now = que.popleft()
        after.append(now)
        for j in A[now]:
            if j in after:
                continue
            if j in que:
                continue
            que.appendleft(j)
        if end in que:
            B = 1
            break
    if B != 1:
        ans += 1
print(ans)

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
inf=10**9


def BFS(s,num):
    color=["white" for _ in range(n+1)]
    D=[inf for _ in range(n+1)]
    M=[[] for _ in range(n+1)]

    for i in range(m):
        if i==num:continue
        a,b=AB[i]
        M[a].append(b)
        M[b].append(a)

    D[s]=0
    color[s]="gray"

    queue=deque([s])
    while len(queue)>0:
        u=queue.popleft()
        for i in M[u]:
            if color[i]=="white":
                D[i]=D[u]+1
                color[i]="gray"
                queue.append(i)
        color[u]="black"

    return True if inf in D[1:] else False


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

cnt=0
for i in range(m):
    cnt +=BFS(1,i)
print(cnt)

Solution (Python):
class UnionFindVerSize:
    def __init__(self, n):
        
        self.par = [i for i in range(n + 1)]
        
        self.size = [1] * (n + 1)

    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 is_same(self, x, y):
        
        return self.find(x) == self.find(y)

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

        
        if self.size[x] < self.size[y]:
            self.par[x] = y
            self.size[x] += self.size[y]
        else:
            self.par[y] = x
            self.size[y] += self.size[x]

    def get_size(self, x):
        return self.size(self.find(x))

    def get_group_num(self):
        ans = 0
        for i in range(1, len(self.par)):
            if self.find(i) == i:
                ans += 1
        return ans

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

ans = 0
for ignore in range(0, M):
    union = UnionFindVerSize(N)
    for i, q in enumerate(query):
        if i == ignore:
            continue
        union.unite(q[0], q[1])

    if union.get_group_num() >= 2:
        ans += 1

print(ans)

Solution (Python):
import sys














stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline()


def main():
    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())

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

    ans = 0
    for i in range(m):
        que = UnionFind(n)
        for j in range(m):
            if i!=j:
                que.union(d[j][0], d[j][1])

        if que.group_count() != 1:
            ans+=1

    print(ans)





if __name__ == '__main__':
    main()

Solution (Python):
import sys














stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline()


def main():
    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())

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

    ans = 0
    for i in range(m):
        que = UnionFind(n)
        for j in range(m):
            if i!=j:
                que.union(d[j][0], d[j][1])

        if que.group_count() != 1:
            ans+=1

    print(ans)





if __name__ == '__main__':
    main()

Solution (Python):
from collections import deque
n,m=map(int,input().split())
ab=[list(map(int,input().split())) for _ in range(m)]
g=[[]for _ in range(n)]

for a,b in ab:
  g[a-1].append(b-1)
  g[b-1].append(a-1)

def bfs(i,j):
  seen=[[-1]for _ in range(n)]
  seen[i]=[]
  todo=deque([[i]])
  c=0
  while len(todo)>0:
    d=todo.pop()
    l=g[d[-1]]
    for li in l:
      if li in d:
        continue
      if li==j:
        c+=1
        if c>1:
          return True
        continue
      e=d.copy()
      e.append(li)
      todo.append(e)
  return False

ans=0
for a,b in ab:
  ans+= 0 if bfs(a-1,b-1) else 1
print(ans)