#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> path;
vector<vector<pair<int, int> > > Rail(405);
vector<vector<int> > Road(405);
set<pair<int, int> > used;
int vis[500];
int cost[500];
int per[500];
int main() {
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    Rail[x].push_back({1, y});
    Rail[y].push_back({1, x});
    used.insert({x, y});
  }
  for (int i = 1; i <= n - 1; i++) {
    for (int j = i + 1; j <= n; j++) {
      if (used.find({i, j}) != used.end() || used.find({j, i}) != used.end())
        continue;
      Road[i].push_back(j);
      Road[j].push_back(i);
    }
  }
  for (int i = 0; i < 500; i++) cost[i] = 1e8;
  memset(per, -1, sizeof per);
  priority_queue<pair<int, int> > pq;
  cost[1] = 0;
  pq.push({0, 1});
  while (!pq.empty()) {
    long long node = pq.top().second;
    pq.pop();
    for (long long i = 0; i < Rail[node].size(); i++) {
      long long n_node_w = Rail[node][i].first;
      long long n_node = Rail[node][i].second;
      if (cost[n_node] > n_node_w + cost[node]) {
        cost[n_node] = n_node_w + cost[node];
        per[n_node] = node;
        pq.push({-1 * cost[n_node], n_node});
      }
    }
  }
  int ans = 1e8;
  queue<pair<int, int> > q;
  q.push({1, 0});
  while (!q.empty()) {
    int node = q.front().first;
    int level = q.front().second;
    if (node == n) {
      ans = level;
      break;
    }
    q.pop();
    for (int i = 0; i < Road[node].size(); i++) {
      int n_node = Road[node][i];
      if (vis[n_node]) continue;
      vis[n_node] = 1;
      q.push({n_node, level + 1});
    }
  }
  int h = n;
  int rail_cost = cost[n];
  if (ans >= 1e8 || cost[n] >= 1e8)
    cout << -1;
  else
    cout << max(cost[n], ans);
  return 0;
}
