#include <bits/stdc++.h>
using namespace std;
struct Event {
  int when, type, id, vert;
  Event(int iwhen, int itype, int iid, int ivert) {
    when = iwhen;
    type = itype;
    id = iid;
    vert = ivert;
  }
  bool operator<(const Event &a) const {
    if (when != a.when) return when > a.when;
    if (type != a.type) return type > a.type;
    if (id != a.id) return id > a.id;
    return vert > a.vert;
  }
};
struct Edge {
  int u, v, uxv, l, r;
  Edge() {}
  Edge(int iu, int iv, int il, int ir) {
    u = iu;
    v = iv;
    l = il;
    r = ir;
    uxv = u ^ v;
  }
};
const int C = 0;
const int O = 1;
const int E = 2;
const int Z = 3;
const int N = 1e6 + 16;
const int INF = 2e9;
int mndist[N];
Edge edges[N];
set<int> g[N], gun[N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  cout << setprecision(32);
  int n, m;
  cin >> n >> m;
  priority_queue<Event> pq;
  for (int i = 0; i < m; i++) {
    int u, v, l, r;
    cin >> u >> v >> l >> r;
    u--;
    v--;
    edges[(i << 1) | 0] = Edge(2 * u, 2 * v + 1, l, r);
    edges[(i << 1) | 1] = Edge(2 * u + 1, 2 * v, l, r);
    pq.push(Event(l, O, (i << 1) | 0, -1));
    pq.push(Event(l, O, (i << 1) | 1, -1));
    pq.push(Event(r, C, (i << 1) | 0, -1));
    pq.push(Event(r, C, (i << 1) | 1, -1));
  }
  for (int i = 0; i < (n << 1); i++) {
    mndist[i] = INF;
  }
  mndist[0] = 0;
  bool flag_start = false;
  while (!pq.empty()) {
    if (mndist[2 * n - 2] != INF || mndist[2 * n - 1] != INF) break;
    Event e = pq.top();
    pq.pop();
    if (!flag_start) {
      if (e.when != 0) {
        break;
      }
      flag_start = true;
    }
    if (e.type == O) {
      int u = edges[e.id].u;
      int v = edges[e.id].v;
      gun[u].insert(e.id);
      gun[v].insert(e.id);
      {
        int when = e.when;
        if ((u ^ when) & 1) when++;
        if (when + 1 <= edges[e.id].r) {
          pq.push(Event(when, E, e.id, u));
        }
      }
      {
        int when = e.when;
        if ((v ^ when) & 1) when++;
        if (when + 1 <= edges[e.id].r) {
          pq.push(Event(when, E, e.id, v));
        }
      }
    } else if (e.type == C) {
      int u = edges[e.id].u;
      int v = edges[e.id].v;
      gun[u].erase(e.id);
      gun[v].erase(e.id);
      g[u].erase(e.id);
      g[v].erase(e.id);
      if (g[u].empty() && gun[u].empty()) {
        if (mndist[u] != INF && (mndist[u] ^ e.when) % 2 == 0) {
          pq.push(Event(e.when, Z, -1, u));
        } else {
          mndist[u] = INF;
        }
      }
      if (g[v].empty() && gun[v].empty()) {
        if (mndist[v] != INF && (mndist[v] ^ e.when) % 2 == 0) {
          pq.push(Event(e.when, Z, -1, v));
        } else {
          mndist[v] = INF;
        }
      }
    } else if (e.type == E) {
      int u = e.vert;
      int v = u ^ edges[e.id].uxv;
      if (mndist[u] <= e.when && e.when + 1 < mndist[v]) {
        mndist[v] = e.when + 1;
        for (int id : gun[v]) {
          if (mndist[v] + 1 <= edges[id].r) {
            pq.push(Event(mndist[v], E, id, v));
          }
          g[v].insert(id);
        }
        gun[v].clear();
      }
    } else {
      int u = e.vert;
      if (g[u].empty() && gun[u].empty()) {
        mndist[u] = INF;
      }
    }
  }
  int ans = min(mndist[2 * n - 2], mndist[2 * n - 1]);
  if (ans != INF) {
    cout << ans << '\n';
  } else {
    cout << -1 << '\n';
  }
  return 0;
}
