#include <bits/stdc++.h> using namespace std; #define int long long #define F first #define S second const int INF = 1e18; vector<int> BFS(int s, vector<vector<int>>& adj) { int n = (int)adj.size(); vector<int> dist(n, INF); dist[s] = 0; queue<int> q; q.push(s); while (!q.empty()) { int x = q.front(); q.pop(); for (int node : adj[x]) { if (dist[node] > dist[x] + 1) { dist[node] = dist[x] + 1; q.push(node); } } } return dist; } vector<int> Dijkstra(int s, vector<vector<pair<int, int>>>& adj, int a, int b) { int n = (int)adj.size(); vector<int> dist(n, INF); vector<bool> vis(n, false); dist[s] = 0; priority_queue<pair<int, int>> q; q.push({0, s}); while (!q.empty()) { int x = q.top().second; q.pop(); if (vis[x]) continue; vis[x] = true; for (pair<int, int> pr : adj[x]) { int node = pr.first; int w = pr.second; if ((x == a && node == b) || (x == b && node == a)) continue; if (dist[node] > dist[x] + w) { dist[node] = dist[x] + w; q.push({-dist[node], node}); } } } return dist; } signed main() { ios::sync_with_stdio(0); cin.tie(0); int n, m; cin >> n >> m; vector<vector<int>> adj(n); for (int i = 0; i < m; i++) { int s, t; cin >> s >> t; s--; t--; adj[s].push_back(t); adj[t].push_back(s); } vector<int> dist = BFS(n-1, adj); vector<int> useful(n, -1); for (int i = 1; i < n-1; i++) { for (int node : adj[i]) { if (dist[node] <= dist[i]) { if (useful[i] != -1) {useful[i] = -1; break;} else useful[i] = node; } } } vector<vector<pair<int, int>>> nwAdj(n); for (int i = 0; i < n; i++) { if (i != 0 && useful[i] != -1) continue; for (int node : adj[i]) { if (node != 0 && useful[node] != -1) { nwAdj[i].push_back({useful[node], dist[node] - dist[useful[node]] + 1}); nwAdj[useful[node]].push_back({i, dist[node] - dist[useful[node]] + 1}); } else { nwAdj[i].push_back({node, 1}); nwAdj[node].push_back({i, 1}); } } } priority_queue<pair<int, int>> q; vector<int> cost(n, INF); cost[n-1] = 0; q.push({0, n-1}); vector<bool> vis(n, false); while (!q.empty()) { int x = q.top().second; q.pop(); if (vis[x]) continue; vis[x] = true; int mn1 = INF, mn2 = INF; for (pair<int, int> pr : nwAdj[x]) { int node = pr.first; int w = pr.second; if (dist[node] >= dist[x] + w) continue; if (mn1 > dist[node] + w) { mn2 = mn1; mn1 = dist[node] + w; } else if (mn2 > dist[node] + w) mn2 = dist[node] + w; } if (x == n-1) { for (pair<int, int> pr : nwAdj[x]) { int node = pr.first; int w = pr.second; if (cost[node] >= cost[x] + w) { cost[node] = cost[x] + w; q.push({-cost[node], node}); } } }else if (mn2 == INF) { assert(x == 0); int other = -1; for (pair<int, int> pr : nwAdj[x]) { int node = pr.first; int w = pr.second; if (dist[node] >= dist[x] + w) continue; other = node; } vector<int> dist2 = Dijkstra(n-1, nwAdj, 0, other); cost[0] = max(cost[0], dist2[0]); } else { cost[x] = max(cost[x], mn2); for (pair<int, int> pr : nwAdj[x]) { int node = pr.first; int w = pr.second; if (cost[node] >= cost[x] + w) { cost[node] = cost[x] + w; q.push({-cost[node], node}); } } //cout << "x " << x << " cost " << cost[x] << "\n"; } } if (cost[0] == INF) cout << -1 << "\n"; else cout << cost[0] << "\n"; }