CodeEff/ECCO huggingface dataset:
# Original solution
from collections import deque

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

edges = []
connections = {}
for i in range(M):
    edges.append(list(map(int,input().split())))
    a,b = edges[-1][0],edges[-1][1]
    
    if a in connections:
        connections[a].append(b)
    else:
        connections[a] = [b]
    
    if b in connections:
        connections[b].append(a)
    else:
        connections[b] = [a]

ans = 0
for i in range(M):
    queue = deque([1])
    checked = [0]*(N+1)
    checked[1] = 1
    NG = {edges[i][0],edges[i][1]}
    
    while queue:
        currentpoint = queue.popleft()
        for nextpoint in connections[currentpoint]:
            if not (currentpoint in NG and nextpoint in NG) and checked[nextpoint] == 0:
                queue.append(nextpoint)
                checked[nextpoint] = 1
            
    if sum(checked) != N:
        ans += 1
        
print(ans)

# Optimized solution
#https://note.nkmk.me/python-union-find/
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 main():
    N,M = list(map(int,input().split()))
    ab = [list(map(int,input().split())) for i in range(M)]
    
    uf = UnionFind(N+1)
    for i in range(M):
        uf.union(ab[i][0],ab[i][1])
    base = uf.group_count()
    
    ans = 0
    for skip in range(M):
        uf = UnionFind(N+1)
        for i in range(M):
            if skip == i:
                continue
            else:
                uf.union(ab[i][0],ab[i][1])
        if uf.group_count()-base == 1:
            ans += 1
    print(ans)
    
if __name__ == '__main__':
    main()
# Original solution
from collections import deque

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

al = [0] * m
bl = [0] * m

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

ans = 0
for i in range(m):
    x, y = al[i], bl[i]
    q = deque()
    q.append(1)
    seen = {1}
    while q:
        v = q.pop()
        for t in eg[v]:
            if t in seen:
                continue
            elif (v == x and t == y) or (v == y and t == x):
                continue
            q.append(t)
            seen.add(t)
    if len(seen) != n:
        ans += 1
print(ans)


# Optimized solution
n, m = list(map(int, input().split()))
eg = [[] for _ in range(n + 1)]

al = [0] * m
bl = [0] * m

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

ans = 0
for i in range(m):
    x, y = al[i], bl[i]
    q = [1]
    seen = {1}
    while len(q) > 0:
        v = q.pop()
        for t in eg[v]:
            if t in seen:
                continue
            elif (v == x and t == y) or (v == y and t == x):
                continue
            q.append(t)
            seen.add(t)
    if len(seen) != n:
        ans += 1
print(ans)
# Original solution
from collections import deque

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

al = [0] * m
bl = [0] * m

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

ans = 0
for i in range(m):
    x, y = al[i], bl[i]
    q = deque()
    q.append(1)
    seen = {1}
    while q:
        v = q.pop()
        for t in eg[v]:
            if t in seen:
                continue
            elif (v == x and t == y) or (v == y and t == x):
                continue
            q.append(t)
            seen.add(t)
    if len(seen) != n:
        ans += 1
print(ans)


# Optimized solution
from collections import deque

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

al = [0] * m
bl = [0] * m

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

ans = 0
for i in range(m):
    x, y = al[i], bl[i]
    q = deque()
    q.append(1)
    seen = {1}
    while len(q) > 0:
        v = q.pop()
        for t in eg[v]:
            if t in seen:
                continue
            elif (v == x and t == y) or (v == y and t == x):
                continue
            q.append(t)
            seen.add(t)
    if len(seen) != n:
        ans += 1
print(ans)
# Original solution
def warshall_floyd(d):
    #d[i][j]: iからjへの最短距離
    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

n,m = list(map(int,input().split())) #n:頂点数　w:辺の数
l=[list(map(int,input().split())) for i in range(m)]
ans=0

#d[u][v] : 辺uvのコスト(存在しないときはinf)
for j in range(m):
	d = [[float("inf") for i in range(n)] for i in range(n)]
	b=l[:j]+l[j+1:]
	for i in range(m-1):
		x,y = b[i][0],b[i][1]
		x-=1;y-=1
		d[x][y] = 1
		d[y][x] = 1
	for i in range(n):
		d[i][i] = 0 #自身のところに行くコストは０
	#print(warshall_floyd(d))
	for i in range(n):
		for k in range(n):
			if warshall_floyd(d)[i][k]==float("inf"):
				ans+=1
				break
		else:
			continue
		break
	#print(ans)
print(ans)

# Optimized solution
import heapq
def dijkstra_heap(s):
    #始点sから各頂点への最短距離
    d = [float("inf")] * n
    used = [True] * n #True:未確定
    d[s] = 0
    used[s] = False
    edgelist = []
    for e in edge[s]:
        heapq.heappush(edgelist,e)
    while len(edgelist):
        minedge = heapq.heappop(edgelist)
        #まだ使われてない頂点の中から最小の距離のものを探す
        if not used[minedge[1]]:
            continue
        v = minedge[1]
        d[v] = minedge[0]
        used[v] = False
        for e in edge[v]:
            if used[e[1]]:
                heapq.heappush(edgelist,[e[0]+d[v],e[1]])
    return d

n,w = list(map(int,input().split()))
l=[list(map(int,input().split())) for i in range(w)]
ans=0
#edge[i] : iから出る道の[重み,行先]の配列
for j in range(w):
    edge = [[] for i in range(n)]
    b=l[:j]+l[j+1:]
    for i in range(w-1):
        x,y = b[i][0],b[i][1]
        x-=1;y-=1
        z=1
        edge[x].append([z,y]) #有向辺
        edge[y].append([z,x]) #有向辺
    if float("inf") in dijkstra_heap(0):
            ans+=1
print(ans)
# Original solution
N, M = [int(_) for _ in input().split()]

paths = [[0] * (N + 1) for _ in range(N + 1)]


def has_path(c, t, arrived):
    if c == t: return True
    for i in range(1, N + 1):
        if i in arrived: continue
        if paths[c][i]:
            arrived.append(i)
            if has_path(i, t, arrived):
                return True
            arrived.pop()
    return False


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

ans = 0
for e in edge:
    paths[e[0]][e[1]] = 0
    paths[e[1]][e[0]] = 0
    if not has_path(e[0], e[1], []):
        ans += 1
    paths[e[0]][e[1]] = 1
    paths[e[1]][e[0]] = 1
print(ans)

# Optimized solution
N, M = [int(_) for _ in input().split()]

paths = [[0] * (N + 1) for _ in range(N + 1)]

edges = []
for i in range(M):
    a, b = [int(_) for _ in input().split()]
    paths[a][b] = 1
    paths[b][a] = 1
    edges.append((a, b))


class UF:
    def __init__(self, v):
        self.parent = None
        self.val = v

    @property
    def root(self):
        if not self.parent:
            return self
        return self.parent.root

    def __str__(self):
        if self.parent:
            return str(self.val) + ' ' + str(self.parent.val)
        return str(self.val) + ' None'


def merge(u1, u2):
    r1 = u1.root
    r2 = u2.root
    if r1 == r2:
        return
    r1.parent = r2


def chk(a, b):
    nodes = [UF(i) for i in range(N + 1)]
    for i in range(1, N):
        for j in range(i + 1, N + 1):
            if paths[i][j]:
                merge(nodes[i], nodes[j])
    return int(nodes[a].root != nodes[b].root)


ans = 0
for e in edges:
    paths[e[0]][e[1]] = 0
    paths[e[1]][e[0]] = 0
    ans += chk(e[0], e[1])
    paths[e[0]][e[1]] = 1
    paths[e[1]][e[0]] = 1
print(ans)
# Original solution
N,M=[int(i) for i in input().split()]
graph = [[] for _ in range(N+1)]
from collections import deque
aa = [0] * M
bb = [0] * M
ans = 0
for i in range(M):
    a,b = [int(j) for j in input().split()]
    graph[a].append(b)
    graph[b].append(a)
    aa[i] = a
    bb[i] = b
import copy
grapha = copy.deepcopy(graph)
for k in range(M):
    graph[aa[k]].remove(bb[k])
    graph[bb[k]].remove(aa[k])
    seen = [False] * (N+1)
    from collections import deque
    que = deque()
    que.append(1)
    while len(que) != 0:
        x = que.popleft()
        seen[x] = True
        for i in graph[x]:
            if seen[i]:
                continue
            que.append(i)
            seen[i] = True
    for l in range(1,N+1):
        if seen[l]:
            continue
        ans +=1
        break
    graph = copy.deepcopy(grapha)
print(ans)

# Optimized solution
#template
def inputlist(): return [int(j) for j in input().split()]
from collections import Counter
#template
#issueから始める
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]
N,M = inputlist()
ans = 0
ab = [0]*M
for i in range(M):
    ab[i] = inputlist()
for i in range(M):
    uf = UnionFind(N)
    for j in range(M):
        if j == i:
            continue
        uf.union(ab[j][0]-1,ab[j][1]-1)
    if len(uf.roots()) != 1:
        ans +=1
print(ans)
# Original solution
import copy 
#深さ優先探索
def dfs(node, E_st_tmp):
      
    #辺の集合が存在しないとき
    if len(E_st_tmp) == 0:
        #全ての頂点を覗いた時
        if not (False in V_look):
            return 
        else:#辺の集合もないし、頂点もない。
            return 
    elif not (False in V_look): #辺の集合があっても全部見る時ある。
        return 

    #ここで探索する
    for i in range(V):
        E_st_tmp_copy   = copy.copy(E_st_tmp)

        if {node, i} in E_st_tmp_copy:
            V_look[i] = True
            E_st_tmp_copy.remove({node, i})
            dfs(i, E_st_tmp_copy)
    
    return

    
#連結かどうかのチェックする
V, E = list(map(int, input().split()))

V_set = [v for v in range(V)]

E_set = []
for _ in range(E):
    a,b = list(map(int, input().split()))
    E_set.append({a-1, b-1})

count = 0

for edge in E_set:
    E_set_cut = copy.copy(E_set)
    E_set_cut.remove(edge)
    #全ての頂点を覗いたか?
    V_look = [False] * V
    V_look[0] = True

    #深さ優先探索
    for v in range(V):
        E_set_copy  = copy.copy(E_set_cut)

        if {0, v} in E_set_copy:
            V_look[v] = True
            E_set_copy.remove({0, v})
            flg_t = dfs(v, E_set_copy)
    if (False in V_look):
        count += 1
        

print(count)



# Optimized solution
import sys
import copy


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

V = []
E = []

for i in range(N):
    V.append(set())

seen = []
seen = [False] * N

count = 0
def dfs(node):
    global V
    global seen

    #注目ノードは訪問済みか?
    if seen[node]==True:
        return
    
    seen[node]=True

    for next_node in V[node]:
        dfs(next_node)
    return

for i in range(M):
    *l,  = list(map(int, input().split()))
    V[l[0]-1].add(l[1]-1)
    V[l[1]-1].add(l[0]-1)
    E.append([l[0]-1, l[1]-1])



E_copy = copy.deepcopy(E)
V_copy = copy.deepcopy(V)
seen_copy = copy.deepcopy(seen)


for i in range(M):
    e = [E[i][0], E[i][1]]
    
    V[e[0]].remove(e[1])
    V[e[1]].remove(e[0])
    
    dfs(0)
    if (False in seen):
        count = count + 1
    seen = [False] * N
    V = copy.deepcopy(V_copy)
   
print(count)
# Original solution
import copy
N,M = list(map(int,input().split()))
graph = [[] for _ in range(N)]
edges = []
for _ in range(M):
    a,b = list(map(int,input().split()))
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)
    edges.append([a-1,b-1])


def dfs(G,v):
    seen[v] = True
    #print(seen)
    for nv in G[v]:
        #print(nv)
        if seen[nv]:
            continue
        dfs(G,nv)

ans = 0
for edge in edges:
    seen = [False] * N
    copied_graph = copy.deepcopy(graph)
    copied_graph[edge[0]].remove(edge[1])
    copied_graph[edge[1]].remove(edge[0])
    dfs(copied_graph,0)
    if not all(seen):
        ans += 1

print(ans)

# Optimized solution
N,M = list(map(int,input().split()))



def find(x):
    if par[x] < 0:
        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 False
    else:
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y]
        par[y] = x
        return True

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

def size(x):
    return -par[find(x)]

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

# 一つの辺以外を繋いでその辺の両端の点が同じ集合に属していたらその辺は橋ではない
ans = 0
for i in range(M):
    par = [-1] * (N + 1)
    for j in range(M):
        if i != j:
            unite(a[j],b[j])
    if not same(a[i],b[i]):
        ans += 1
print(ans)
# Original solution
def DFS(N, copyedge):
    matrix = [[] for i in range(N)]
    for a, b in copyedge:
        matrix[a].append(b)
        matrix[b].append(a)
        
    check = [True]*N
    check[0] = False
    Que = [0]

    while len(Que) != 0:
        now = Que.pop()
        for i in matrix[now]:
            if check[i] == True:
                check[i] = False
                Que.append(i)
    if True not in check:
        return 0
    else:
        return 1
            
        

ans = 0
N, M = list(map(int, input().split()))
edge = []

for i in range(M):
    edge.append([int(i) - 1 for i in input().split()])
    
for i in range(M):
    copyedge = edge[:i] + edge[i+1:] 
    ans += DFS(N, copyedge)
print(ans)

# Optimized solution
N, M = list(map(int, input().split()))
ab = [[] for i in range(M)]
ans = 0
for i in range(M):
    a, b = list(map(int, input().split()))
    a, b = a-1, b-1
    ab[i] = [a, b]

def cal(AB):
    matrix = [[] for i in range(N)]
    for a, b in AB:
        matrix[a].append(b)
        matrix[b].append(a)
    check = [0] * N
    check[0] = 1
    deque = [0]
    while deque:
        now = deque.pop()
        for i in matrix[now]:
            if check[i] == 0:
                deque.append(i)
                check[i] = 1
    if len(set(check)) == 1:
        return 0
    else:
        return 1

for i in range(M):
    AB = ab[:]
    del AB[i]
    ans += cal(AB)

print(ans)
# Original solution
from collections import deque
n, m = list(map(int, input().split()))
E = [[*[int(x)-1 for x in input().split()]] for _ in range(m)]
V = [[] for _ in range(n)]
for a,b in E:
    V[a].append(b)
    V[b].append(a)

def dfs(a,b,f,i):
    # if i>=n:
    #     return
    if vis[f] == 1: return
    vis[f] = 1
    # print('f',f)
    for t in V[f]:
        if f==a and t == b: continue
        # if t == b: continue
        if vis[t] == 1: continue
        # print(t)
        dfs(a,b,t,i+1)

ans = 0
for a, b in E:
    vis = [0]*n
    dfs(a,b,a,1)
    # print(a,b,vis)
    if vis[b] == 0:
        ans += 1
    # print('----')

# print(E)
# print(V)

print(ans)


# Optimized solution
n, m = list(map(int, input().split()))
E = [[*[int(x)-1 for x in input().split()]] for _ in range(m)]

V = [[] for _ in range(n)]
for a, b in E:
    V[a].append(b)
    V[b].append(a)

def dfs(a, b, f):
    if vis[f] == 1: return
    vis[f] = 1
    for t in V[f]:
        if f==a and t == b: continue
        dfs(a, b, t)

ans = 0
for a, b in E:
    vis = [0]*n
    dfs(a, b, a)
    if vis[b] == 0: ans += 1
print(ans)
# Original solution
from collections import deque
 
def dfs(n, start, graph):
  visited = [False] * n
  stack = deque()
  stack.append(start)
  visited[start] = True
  while stack:
    q = stack.popleft()
    nxts = graph[q]
    for nxt in nxts:
      if not visited[nxt]:
        visited[nxt] = True
        stack.append(nxt)
  return visited
 
n, m = list(map(int, input().split()))
edge = [list(map(int, input().split())) for _ in range(m)]
 
ans = 0
for i in range(m):
  graph = [[] for _ in range(n)]
  for itr, (a, b) in enumerate(edge):
    if itr != i:
      graph[a - 1].append(b - 1)
      graph[b - 1].append(a - 1)
 
  if not all(dfs(n, 0, graph)):
    ans += 1
print(ans)

# Optimized solution
n,m=list(map(int,input().split()))
edge=[[] for _ in range(n+1)]
eab=[]
for i in range(m):
    a,b=list(map(int,input().split()))
    edge[a-1].append(b-1)
    edge[b-1].append(a-1)
    eab.append([a-1,b-1])
 
def dfs(visited,count,node):
    visited[node]=True
    count+=1
    ev=edge[node]
    for node in ev:
        if visited[node]:
            continue
        else:
            count=dfs(visited,count,node)
    return count

ans=0
for i in range(m):
    a,b=eab[i]
    edge[a].remove(b)
    edge[b].remove(a)
    ci=dfs([False for _ in range(n)],0,0)
    if ci!=n:
        ans+=1
    edge[a].append(b)
    edge[b].append(a)
print(ans)
# Original solution
from collections import defaultdict as dd
n,m = list(map(int, input().split()))
dic = dd(list)
l = []
cnt = 0
for _ in range(m):
  a,b = list(map(int, input().split()))
  l.append((a,b))
  dic[a].append(b)
  dic[b].append(a)
def con(x):
  visit.add(x)
  for i in dic[x]:
    if i in visit:
      continue
    con(i)
  return visit == set(range(1,n+1))
for x,y in l:
  dic[x].remove(y)
  dic[y].remove(x)
  visit = set()
  if not con(x):
    cnt += 1
  dic[x].append(y)
  dic[y].append(x)
print(cnt)

# Optimized solution
int1 = lambda x: int(x) - 1

N, M = list(map(int, input().split()))
G = [list() for _ in range(N)]
edges = [tuple(map(int1, input().split())) for _ in range(M)]
for u,v in edges:
    G[u].append(v)
    G[v].append(u)

pre = [-1]*N
low = [-1]*N

def detect_bridge(v, p=None, c=0):
    ret = list()
    pre[v] = low[v] = c
    c += 1
    for x in G[v]:
        if x == p: continue
        if pre[x] < 0:
            br, c = detect_bridge(x, v, c)
            ret.extend(br)
             
        if low[v] > low[x]: low[v] = low[x]
    if pre[v] == low[v] > 0:
        ret.append((p, v))
    return ret, c

bridges, _ = detect_bridge(0)
print((len(bridges)))
# Original solution
from collections import deque
from collections import defaultdict
edges = defaultdict(list)
N,M = list(map(int, input().split()))
pairs = []
for i in range(M):
    a,b  = list(map(int, input().split()))
    a -= 1
    b -= 1
    pairs.append((a,b))
ans = 0
# M本目の辺を切って全探索
for i in range(M):
    edges = defaultdict(list)
    s = 0
    for j,(a,b) in enumerate(pairs):
        if i == j:continue
        edges[a].append(b)
        edges[b].append(a)
        s = b
    cnt = 0
    # print(i,edges)
    # bfs
    seen = [False] * N 
    q = deque()
    q.append(b) 
    while len(q) > 0:
        e = q.popleft()
        nx = edges[e]
        for n in nx:
            if seen[n]:continue
            seen[n] = True
            q.append(n)
    if sum(seen) != N:
        ans += 1


    
print(ans)



# Optimized solution
"""
DFS
"""
from collections import defaultdict
N,M = list(map(int, input().split()))
pairs = []
for i in range(M):
    a,b = list(map(int, input().split()))
    a -= 1
    b -= 1
    pairs.append((a,b))


def dfs(s):
    global visited,edges
    if visited[s]:return 0
    visited[s] = True
    ns = edges[s]
    for n in ns:
        dfs(n)
    
    
ans = 0  
for i in range(M):
    edges = defaultdict(list)
    visited = [False] * N
    for j,(a,b) in enumerate(pairs):
        if i == j: continue
        edges[b].append(a)
        edges[a].append(b)
    dfs(0)
    if sum(visited) != N:
        ans += 1
print(ans)
# Original solution
def main():
    from collections import deque

    def traversal(ignore_idx):
        s = 0
        visited = [-1] * N
        visited[s] = 0

        dq = deque([s])
        while dq:
            v = dq.popleft()
            for u, edge_idx in g[v]:
                if ~visited[u] or edge_idx == ignore_idx:
                    continue
                dq.append(u)
                visited[u] = 0
        return all(~flg for flg in visited)  # 連結ならTrue

    N, M = list(map(int, input().split()))
    g = tuple(set() for _ in range(N))
    for edge_idx in range(M):
        a, b = (int(x) - 1 for x in input().split())
        g[a].add((b, edge_idx))
        g[b].add((a, edge_idx))

    ret = 0
    for ignore_idx in range(M):
        res = traversal(ignore_idx)
        if not res:
            ret += 1
    print(ret)


if __name__ == '__main__':
    main()


# Optimized solution
def main():
    from collections import deque

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

    g = tuple(set() for _ in range(N))
    es = []
    for _ in range(M):
        a, b = (int(x) - 1 for x in input().split())
        g[a].add(b)
        g[b].add(a)
        es.append((a, b))

    cnt = 0
    for e in es:
        v = 0

        dq = deque()
        dq.append(v)
        used = [False] * N
        used[v] = True

        while dq:
            v = dq.popleft()
            for u in g[v]:
                if used[u]: continue
                if (v, u) == e or (u, v) == e: continue
                used[u] = True
                dq.append(u)

        if all(used): continue
        cnt += 1

    print(cnt)


if __name__ == '__main__':
    main()

# import sys
#
# sys.setrecursionlimit(10 ** 7)
#
# input = sys.stdin.readline
# rstrip()
# int(input())
# map(int, input().split())