#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;
}
template <typename T>
inline bool smin(T &a, const T &b) {
  return a > b ? a = b : a;
}
template <typename T>
inline bool smax(T &a, const T &b) {
  return a < b ? a = b : a;
}
const int N = (int)3e6 + 6, mod = (int)0;
vector<int> adj[N], ex[N][2];
int eu[N], ev[N], el[N], er[N], d[N];
int by_l(int first, int second) { return el[first >> 2] > el[second >> 2]; }
int main() {
  ios_base::sync_with_stdio(0);
  int n, m;
  cin >> n >> m;
  if (n == 1) {
    cout << 0 << endl;
    return 0;
  }
  for (int e = 0; e < m; ++e) {
    int a = e << 2 | 0, b = a | 1, c = a | 2, d = a | 3;
    int &u = eu[e], &v = ev[e], &l = el[e], &r = er[e];
    cin >> u >> v >> l >> r;
    --u, --v, ++r;
    if (u > v) swap(u, v);
    ex[u][0].push_back(a);
    ex[u][1].push_back(b);
    ex[v][0].push_back(c);
    ex[v][1].push_back(d);
    adj[a].push_back(d);
    adj[b].push_back(c);
    adj[d].push_back(a);
    adj[c].push_back(b);
  }
  for (int v = 0; v < n; ++v)
    for (int p = 0; p <= 1; ++p) sort(ex[v][p].begin(), ex[v][p].end(), by_l);
  memset(d, 63, sizeof d);
  set<pair<int, int>> st;
  for (int e = 0; e < m; ++e) {
    int a = e << 2 | 0;
    int &u = eu[e], &v = ev[e], &l = el[e], &r = er[e];
    if (l == 0 && u == 0) {
      d[a] = 0;
      st.insert(make_pair(d[a], a));
    }
  }
  while ((int)st.size()) {
    auto cur = *(st.begin());
    st.erase(cur);
    int ind = cur.second, e = ind >> 2;
    int u = eu[e], v = ev[e], l = el[e], r = er[e], parity = 0;
    if (ind & 2) {
      swap(u, v);
    }
    parity = ind & 1;
    if (d[ind] + 1 < r)
      for (int first : adj[ind]) {
        if (d[ind] + 1 < d[first]) {
          st.erase(make_pair(d[first], first));
          d[first] = d[ind] + 1;
          st.insert(make_pair(d[first], first));
        }
      }
    int curd = cur.first;
    while ((int)ex[u][parity].size()) {
      int nxe = ex[u][parity].back();
      if (curd >= er[nxe >> 2]) {
        ex[u][parity].pop_back();
      } else {
        int after = el[nxe >> 2];
        while ((after ^ parity) & 1) ++after;
        after = max(after, curd);
        if (after >= r) break;
        if (after < er[nxe >> 2]) {
          if (d[nxe] > after) {
            st.erase(make_pair(d[nxe], nxe));
            d[nxe] = after;
            st.insert(make_pair(d[nxe], nxe));
          }
        }
        ex[u][parity].pop_back();
      }
    }
  }
  int res = 2e9;
  for (int j = 0; j < 4 * m; ++j) {
    int e = j >> 2;
    int u = eu[e], v = ev[e], l = el[e], r = er[e];
    if (j & 2) {
      swap(u, v);
    }
    if (u == n - 1) {
      res = min(res, d[j]);
    }
  }
  if (res > (int)1e9 + 10) {
    res = -1;
  }
  cout << res << '\n';
}
