#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T>
inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
const int oo = 0x3f3f3f3f;
const int maxn = 1000100;
const int maxm = 2000100;
int n, m;
struct data {
  int first, second, l, r;
  data() {}
  data(int _x, int _y, int _l, int _r) : first(_x), second(_y), l(_l), r(_r) {}
};
multiset<int> adj[maxn + 5];
data ed[maxm + 5];
map<int, vector<int> > all;
int now;
int dis[maxn + 5];
inline void adde(int first, int second) {
  adj[first].insert(second);
  if (dis[first] <= now && chkmin(dis[second], now + 1)) {
    if (dis[second] < oo) all[dis[second]].push_back((m << 1) + second);
  }
}
inline void dele(int first, int second) {
  adj[first].erase(adj[first].find(second));
}
int main() {
  scanf("%d%d", &n, &m);
  if (n == 1) {
    printf("0\n");
    return 0;
  }
  for (int i = (0), i_end_ = (m); i < i_end_; ++i) {
    int first, second, l, r;
    scanf("%d%d%d%d", &first, &second, &l, &r), --first, --second;
    int l0 = l, l1 = l;
    if (l & 1)
      ++l0;
    else
      ++l1;
    ed[i << 2] = data(first << 1, second << 1 | 1, l0, r);
    ed[i << 2 | 1] = data(second << 1, first << 1 | 1, l0, r);
    ed[i << 2 | 2] = data(first << 1 | 1, second << 1, l1, r);
    ed[i << 2 | 3] = data(second << 1 | 1, first << 1, l1, r);
  }
  memset(dis, oo, sizeof dis);
  m <<= 2;
  for (int i = (0), i_end_ = (m); i < i_end_; ++i)
    if (ed[i].l < ed[i].r) {
      if (!ed[i].l && !ed[i].first) dis[0] = 0;
      all[ed[i].l].push_back(i << 1 | 1);
      all[ed[i].r].push_back(i << 1);
    }
  int ans = oo;
  for (auto uu : all) {
    now = uu.first;
    set<int> to_check;
    set<int> to_expand;
    for (auto u : uu.second) {
      if (u < (m << 1)) {
        int tmp = u >> 1;
        if (u & 1) {
          adde(ed[tmp].first, ed[tmp].second);
        } else {
          dele(ed[tmp].first, ed[tmp].second);
          to_check.insert(ed[tmp].first);
        }
      } else
        to_expand.insert(u - (m << 1));
    }
    for (auto u : to_expand)
      if (dis[u] <= now) {
        for (auto v : adj[u])
          if (chkmin(dis[v], now + 1)) {
            if (dis[v] < oo) all[dis[v]].push_back((m << 1) + v);
          }
      }
    for (auto u : to_check) {
      if (adj[u].empty()) dis[u] = oo;
    }
    chkmin(ans, dis[(n - 1) << 1]);
    chkmin(ans, dis[(n - 1) << 1 | 1]);
  }
  if (ans >= oo)
    printf("-1\n");
  else
    printf("%d\n", ans);
  return 0;
}
