from collections import deque V, E, S, G = map(int, input().split()) can_go_from:list[list[int]] = [[] for _ in range(V+1)] for _ in range(E): A, B = map(int, input().split()) can_go_from[A].append(B) can_go_from[B].append(A) Ord = [0]*(V+1) Low = [0]*(V+1) seen:set[int] = set() dfs = deque([(S, 0)]) # queue of (vtx, parent) trace:list[tuple[int,int]] = [] while dfs: # dfs for lowlink curr, pare = dfs.popleft() if curr in seen: continue seen.add(curr) Ord[curr] = Low[curr] = len(seen) for next in can_go_from[curr]: if next in seen and next != pare: Low[curr] = min(Ord[next], Low[curr]) # 行きがけの処理 else: dfs.appendleft((next, curr)) trace.append((curr, pare)) # 帰りがけ用 for curr, pare in reversed(trace): Low[pare] = min(Low[curr], Low[pare]) INF = 500_000 seen.clear() min_step_from_S_to_G = INF max_spent_circular_from_S_to_G = -1 bfs = deque([(S, 0, 0)]) # queue of (vtx, step, spent_circular) # bfs for answer while bfs: curr, step, cnt = bfs.popleft() if curr in seen: continue if curr == G: if step < min_step_from_S_to_G: min_step_from_S_to_G = step max_spent_circular_from_S_to_G = -1 max_spent_circular_from_S_to_G = max(cnt,max_spent_circular_from_S_to_G) seen.add(curr) # このタイミングでの追加でよい説明は、あとで書く for next in can_go_from[curr]: if next not in seen: bfs.append((next, step + 1, cnt + (1 if Ord[curr] >= Low[next] else 0))) print(max_spent_circular_from_S_to_G)