#include <bits/stdc++.h> using namespace std; const int inf = int(1e9); const int N = int(2e5) + 10; const int M = 2 * 30 * N; int pref[N], suff[N], val[M], ch[M][2], tsz; void Modify(int& x, int px, int l, int r, int p, int v) { x = ++tsz; ch[x][0] = ch[px][0]; ch[x][1] = ch[px][1]; if (px == 0) { val[x] = v; } else { val[x] = min(val[px], v); } if (l == r) { return; } int mid = l + r >> 1; if (p <= mid) { Modify(ch[x][0], ch[px][0], l, mid, p, v); } else { Modify(ch[x][1], ch[px][1], mid + 1, r, p, v); } } int Query(int x, int l, int r, int ll, int rr) { if (ll <= l && r <= rr) { return (x == 0 ? inf : val[x]); } int mid = l + r >> 1; if (rr <= mid) { return Query(ch[x][0], l, mid, ll, rr); } else if (ll > mid) { return Query(ch[x][1], mid + 1, r, ll, rr); } else { return min(Query(ch[x][0], l, mid, ll, rr), Query(ch[x][1], mid + 1, r, ll, rr)); } } int main() { ios::sync_with_stdio(false); cin.tie(0); int n, m; cin >> n >> m; vector<vector<int>> g(n); for (int i = 0; i < m; i++) { int u, v; cin >> u >> v; --u; --v; g[u].push_back(v); g[v].push_back(u); } vector<int> que(1, n - 1); vector<int> dist(n, -1); dist.back() = 0; vector<vector<int>> nei(n); vector<vector<int>> back(n); vector<int> pr(n, -1); for (int b = 0; b < int(que.size()); b++) { int i = que[b]; for (int j : g[i]) { if (dist[j] == -1) { dist[j] = dist[i] + 1; que.push_back(j); nei[i].push_back(j); nei[j].push_back(i); pr[j] = i; } else if (j != pr[i]) { back[i].push_back(j); } } } if (pr[0] == -1) { cout << -1 << '\n'; return 0; } vector<int> d0(n, -1); { d0[0] = 0; vector<int> que(1, 0); for (int b = 0; b < int(que.size()); b++) { int i = que[b]; for (int j : g[i]) { if (d0[j] == -1) { d0[j] = d0[i] + 1; que.push_back(j); } } } } vector<int> who(n); vector<int> dfn(n); vector<int> dfo(n); int T = -1; auto Dfs = [&](auto&& self, int v, int pv) -> void { dfn[v] = ++T; who[T] = v; for (int u : nei[v]) { if (u == pv) { continue; } self(self, u, v); } dfo[v] = T; }; Dfs(Dfs, n - 1, -1); for (int t = 0; t < n; t++) { if (t > 0) { pref[t] = pref[t - 1]; } int i = who[t]; for (int to : back[i]) { Modify(pref[t], pref[t], 0, n - 1, dfn[to], dist[to] + dist[i]); } } for (int t = n - 1; t >= 0; t--) { if (t + 1 < n) { suff[t] = suff[t + 1]; } int i = who[t]; for (int to : back[i]) { Modify(suff[t], suff[t], 0, n - 1, dfn[to], dist[to] + dist[i]); } } auto Best = [&](int v, int l, int r) { int ret = inf; if (l > 0) { ret = min(ret, Query(pref[l - 1], 0, n - 1, l, r) + 1 - dist[v]); } if (r + 1 < n) { ret = min(ret, Query(suff[r + 1], 0, n - 1, l, r) + 1 - dist[v]); } return ret; }; vector<int> val(n); for (int i = 0; i < n; i++) { val[i] = Best(i, dfn[i], dfo[i]); } val[n - 1] = 0; function<bool(int)> Check = [&](int t) { if (val[0] > t) { return false; } vector<int> que(1, 0); vector<int> dist(n, -1); dist[0] = 0; for (int b = 0; b < int(que.size()); b++) { int i = que[b]; for (int j : g[i]) { if (dist[j] == -1 && (val[j] + dist[i] + 1) <= t) { dist[j] = dist[i] + 1; que.push_back(j); } } } if (dist[n - 1] != -1 && dist[n - 1] <= t) { return true; } else { return false; } }; int low = 0, high = inf, res = inf; while (low <= high) { int mid = low + high >> 1; if (Check(mid)) { res = mid; high = mid - 1; } else { low = mid + 1; } } cout << (res == inf ? -1 : res) << '\n'; return 0; }