#include <bits/stdc++.h> using namespace std; using ll = long long; using LL = long long; using i64 = long long; struct SegTree { vector<int> arr; int s; void update(int p, int v) { p += s; arr[p] = v; for (p >>= 1; p; p >>= 1) arr[p] = min(arr[2 * p], arr[2 * p + 1]); } int query(int l, int r) { int ans = 1e9; for (l += s, r += s; l < r; l >>= 1, r >>= 1) { if (l & 1) ans = min(ans, arr[l++]); if (r & 1) ans = min(ans, arr[--r]); } return ans; } SegTree(int n) { s = 1 << (int)ceil(log2(n)); arr.resize(2 * s, 1e9); } }; void solve() { int n, m; cin >> n >> m; vector<vector<int>> adj(n); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; adj[u - 1].push_back(v - 1); adj[v - 1].push_back(u - 1); } queue<tuple<int, int, int>> q; q.emplace(n - 1, -2, 0); vector<int> par(n, -1), dst(n, 1e9); while (!q.empty()) { auto [x, p, d] = q.front(); q.pop(); if (par[x] != -1) continue; par[x] = p; dst[x] = d; for (auto u: adj[x]) q.emplace(u, x, d + 1); } vector<vector<int>> treeadj(n); for (int i = 0; i < n - 1; i++) treeadj[par[i]].push_back(i); int timer = 0; vector<int> tin(n), tout(n); auto dfs1 = [&](auto &&dfs1, int node) -> void { tin[node] = timer++; for (auto u: treeadj[node]) dfs1(dfs1, u); tout[node] = timer; }; dfs1(dfs1, n - 1); SegTree segtree(n); vector<multiset<int>> edges(n); for (int i = 0; i < n; i++) edges[i].insert(1e9); auto score = [&](int lo, int hi) { return dst[hi] + dst[lo]; }; vector<int> adjusted(n); auto dfs = [&](auto &&dfs, int node) -> void { for (auto u: treeadj[node]) { dfs(dfs, u); } for (auto u: adj[node]) { if (tin[node] <= tin[u] && tin[u] < tout[node]) { if (par[u] != node) { edges[u].erase(edges[u].find(score(u, node))); segtree.update(tin[u], *edges[u].begin()); } } else if (u != par[node]) { edges[node].insert(score(node, u)); segtree.update(tin[node], *edges[node].begin()); } } adjusted[node] = segtree.query(tin[node], tout[node]) - dst[node] + 1; }; dfs(dfs, n - 1); adjusted[n - 1] = 0; auto check = [&](int limit) { queue<pair<int, int>> q; q.emplace(0, 0); vector<int> dst(n, 1e9); while (!q.empty()) { auto [x, d] = q.front(); q.pop(); if (dst[x] != 1e9) continue; if (d + adjusted[x] > limit) continue; if (x == n - 1) return true; dst[x] = d; for (auto u: adj[x]) { q.emplace(u, d + 1); } } return false; }; int l = 0, r = 3 * n; while (r - l > 1) { int m = (l + r) / 2; if (check(m)) r = m; else l = m; } if (r == 3 * n) r = -1; cout << r << '\n'; } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); solve(); }