#include <bits/stdc++.h> using namespace std; #define fwd(i, a, n) for(int i = (a); i < (n); i++) #define rep(i, n) fwd(i, 0, n) #define all(X) X.begin(), X.end() #define sz(X) int(size(X)) #define pb push_back #define eb emplace_back #define st first #define nd second using pii = pair<int, int>; using vi = vector<int>; using ll = long long; using ld = long double; #ifdef LOC auto SS = signal(6, [](int) {* (int *) 0 = 0;}); #define DTP(x, y) auto operator << (auto& o, auto a) -> decltype(y, o) {o << "("; x; return o << ")";} DTP(o << a.st << ", " << a.nd, a.nd); DTP(for(auto i : a) o << i << ", ", all(a)); void dump(auto... x) {((cerr << x << ", "), ...) << "\n";} #define deb(x...) cerr << setw(4) << __LINE__ << ":[" #x "]: ", dump(x) #else #define deb(...) 0 #endif #define S 200007 #define C 20 vector<int> V[S]; vector<int> T[S]; vector<int> back[S]; int R[S][C+1]; bool vis[S]; int depth[S]; void BFS(int s) { queue<pair<pair<int,int>, int>> q; q.push({{s,s},0}); while(!q.empty()) { auto [x,r] = q.front().first; int d = q.front().second; q.pop(); if(vis[x]) continue; vis[x] = 1; if(r != x) T[r].pb(x); R[x][0] = r; for(int i = 1; i <= C; i++) { R[x][i] = R[R[x][i-1]][i-1]; } depth[x] = d; for(auto &v: V[x]) { q.push({{v,x}, d+1}); } } } int LCA(int x, int y) { if(depth[y] > depth[x]) swap(x,y); for(int i = C; i >= 0; i--) { if(depth[R[x][i]] >= depth[y]) x = R[x][i]; } if(x == y) return x; for(int i = C; i >= 0; i--) { if(R[x][i] != R[y][i]){ x = R[x][i]; y = R[y][i]; } } return R[x][0]; } vector<int> toDelete[S]; vector<int>* toAdd[S]; int roz[S]; void initDFS(int x) { roz[x] = back[x].size(); for(auto &v: T[x]) { initDFS(v); roz[x] += roz[v]; } } multiset<int> *sett[S]; int ans[S]; void DFS(int x){ // deb(x); int bigChild = -1; int siz = -1; for(auto &v: T[x]) { if(roz[v] > siz) { siz = roz[v]; bigChild = v; } } for(auto &v: T[x]) { DFS(v); } if(bigChild == -1) { toAdd[x] = new vector<int>(); sett[x] = new multiset<int>(); } else { toAdd[x] = toAdd[bigChild]; sett[x] = sett[bigChild]; } for(auto p: back[x]) { toAdd[x]->pb(p); sett[x]->insert(p); } // deb(x, *toAdd[x]); for(auto &v: T[x]) { if(v != bigChild) { for(int i = 0; i < toAdd[v]->size(); i++) { toAdd[x]->push_back(toAdd[v]->at(i)); sett[x]->insert(toAdd[v]->at(i)); } } } deb(x, *toAdd[x], *sett[x]); deb(x, toDelete[x]); for(auto p: toDelete[x]) { sett[x]->erase(sett[x]->lower_bound(p)); } if(sett[x]->empty()) ans[x] = 1e9; else ans[x] = *sett[x]->begin() - depth[x]; } bool good(int k, int n) { for(int i = 1; i <= n; i++) { vis[i] = 0; } queue<pii> q; q.push({1,0}); while(!q.empty()) { auto [x,d] = q.front(); q.pop(); if(vis[x]) continue; vis[x] = 1; if(ans[x] + d > k) continue; for(auto v: V[x]) { q.push({v,d+1}); } } return (vis[n] == 1); } int32_t main(){ cin.tie(0)->sync_with_stdio(0); cout << fixed << setprecision(10); int n,m; cin >> n >> m; for(int i = 1; i <= m; i++) { int a,b; cin >> a >> b; V[a].pb(b); V[b].pb(a); } BFS(n); for(int i = 1; i <= n; i++) { for(auto &v: V[i]) { if(v != R[i][0] && i != R[v][0]) { // back[i].pb(v); back[i].pb(depth[i] + 1 + depth[v]); int lca = LCA(i,v); // toDelete[lca].pb(depth[i] + 1 - depth[v]); toDelete[lca].pb(depth[v] + 1 + depth[i]); } } } for(int i = 1; i <= n; i++){ deb(i, T[i], back[i]); } initDFS(n); DFS(n); // for(int i = 1; i <= n; i++) { // deb(i, ans[i]); // } int l = 1; int r = 3*n; while(l < r) { int sr = (l+r)/2; if(good(sr,n)) { r = sr; } else { l = sr+1; } } if(r == 3*n) { cout << "-1\n"; } else { cout << r << "\n"; } return 0; }