#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <set>

using namespace std;

typedef long long ll;

const int MAXN = 200005;
const ll INF = 20*MAXN;

struct Node {
    vector<int> nei;
    ll ds;
    ll dt;
    ll speciald = INF;
    ll cost = 0;
    ll blockedby = -1;
    bool vis = false;
};

Node graph[MAXN];
int n, m;
int s, t;


void bfsDS() {
    queue<int> q;
    q.push(s);
    graph[s].vis = true;
    graph[s].ds = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : graph[u].nei) {
            if (graph[v].vis) continue;
            graph[v].vis = true;
            graph[v].ds = graph[u].ds + 1;
            q.push(v);
        }
    }
}

void bfsDT() {
    queue<int> q;
    q.push(t);
    graph[t].vis = true;
    graph[t].dt = 0;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : graph[u].nei) {
            if (graph[v].vis) continue;
            graph[v].vis = true;
            graph[v].dt = graph[u].dt + 1;
            q.push(v);
        }
    }
}

void clearvis() {
    for (int i = 0; i < n; i++) {
        graph[i].vis = false;
    }
}

void bfsCOST(ll maxcost) {
    if (graph[s].cost > maxcost) return;
    queue<int> q;
    q.push(s);
    graph[s].vis = true;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int v : graph[u].nei) {
            if (graph[v].vis) continue;
            if (graph[v].cost > maxcost) continue;
            graph[v].vis = true;
            q.push(v);
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        u--; v--;
        graph[u].nei.push_back(v);
        graph[v].nei.push_back(u);
    }
    s = 0;
    t = n-1;
    clearvis();
    bfsDS();
    clearvis();
    bfsDT();
    clearvis();
    vector<int> vxs(n);
    for (int i = 0; i < n; i++) vxs[i] = i;
    sort(vxs.begin(), vxs.end(), [&](const int& a, const int& b) {
        return graph[a].dt < graph[b].dt;
    });
    vector<vector<int>> lvls(n);
    for (int i = 0; i < n; i++) {
        lvls[graph[i].dt].push_back(i);
    }
    for (vector<int>& l : lvls) {
        for (int u : l) {
            if (u == t) {
                graph[u].speciald = 0;
                continue;
            }
            set<int> currblockedby;
            int numlower = 0;
            for (int v: graph[u].nei) {
                if (graph[v].dt < graph[u].dt) {
                    if (graph[v].blockedby != -1) {
                        currblockedby.insert(graph[v].blockedby);
                    } else {
                        numlower++;
                    }
                }
            }
            if (currblockedby.size() + numlower >= 2) {
                for (int i: currblockedby) {
                    graph[i].speciald = min(graph[i].speciald, 2 * graph[u].dt - graph[i].dt);
                }
                graph[u].speciald = graph[u].dt;
            } else if (currblockedby.size() == 1) {
                graph[u].blockedby = *currblockedby.begin();
            } else {
                graph[u].blockedby = u;
            }
        }
        for (int u : l) {
            if (u == t || graph[u].blockedby == -1) {
                continue;
            }
            for (int v: graph[u].nei) {
                if (graph[v].dt == graph[u].dt) {
                    if (graph[v].blockedby != -1 || graph[v].blockedby != graph[u].blockedby) {
                        int i = graph[u].blockedby;
                        graph[i].speciald = min(graph[i].speciald, 2 * graph[u].dt - graph[i].dt + 1);
                        graph[i].blockedby = -1;
                        break;
                    }
                }
            }
        }
    }
    for (int i = 0; i < n; i++) {
        graph[i].cost = min(graph[i].ds + graph[i].speciald, INF);
        if (graph[i].blockedby != -1) {
            graph[i].cost = 0;
        }
    }
    ll lo = 0;
    ll hi = INF-10;
    while (lo < hi) {
        ll mid = (lo + hi) / 2;
        clearvis();
        bfsCOST(mid);
        if (graph[t].vis) {
            hi = mid;
        } else {
            lo = mid + 1;
        }
    }
    if (lo > INF/2) {
        cout << -1 << endl;
    }
    else {
        cout << lo << endl;
    }

    return 0;
}