from types import GeneratorType from collections import deque def bootstrap(f, stack=[]): def wrappedfunc(*args, **kwargs): if stack: return f(*args, **kwargs) to = f(*args, **kwargs) while True: if type(to) is GeneratorType: stack.append(to) to = next(to) else: stack.pop() if not stack: break to = stack[-1].send(to) return to return wrappedfunc class LowLink: def __init__(self, N): self.N = N self.M = 0 self.G = [[] for _ in range(N)] def add_edge(self, u, v): self.G[u].append((v, self.M)) self.G[v].append((u, self.M)) self.M += 1 @bootstrap def dfs(self, n, parent): self.visited[n] = True self.ord[n], self.low[n] = self.cnt, self.cnt self.cnt += 1 is_ap = False child = 0 for v, idx in self.G[n]: if not self.visited[v]: child += 1 yield self.dfs(v, idx) self.low[n] = min(self.low[n], self.low[v]) if parent != -1 and self.ord[n] <= self.low[v]: is_ap = True if self.ord[n] < self.low[v]: self.bridge.append(idx) elif idx != parent: self.low[n] = min(self.low[n], self.ord[v]) if parent == -1 and 2 <= child: is_ap = True if is_ap: self.articulation_points.append(n) yield def find(self): self.ord = [-1]*self.N self.low = [-1]*self.N self.visited = [False]*self.N self.cnt = 0 self.articulation_points = [] self.bridge = [] for i in range(self.N): if not self.visited[i]: self.dfs(i, -1) return sorted(self.articulation_points), sorted(self.bridge) N, M, s, g = map(int, input().split()) G = [[] for _ in range(N)] LL = LowLink(N) for i in range(M): u, v = map(int, input().split()) u, v = u-1, v-1 G[u].append((v, i)) G[v].append((u, i)) LL.add_edge(u, v) s,g = s-1, g-1 _, bridge = LL.find() F = [True]*M for b in bridge: F[b] = False dp = [-1]*N visited = [-1]*N dp[s] = 0 visited[s] = 0 que = deque() que.append(s) while que: n = que.popleft() for v, eidx in G[n]: if visited[v] == -1: visited[v] = visited[n]+1 dp[v] = dp[n]+F[eidx] que.append(v) elif visited[v] == visited[n]+1: dp[v] = max(dp[v], dp[n]+F[eidx]) print(dp[g] if visited[g] != -1 else -1)