#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
inline void wrote(int x) {
  if (x < 0) putchar('-'), x = -x;
  if (x >= 10) wrote(x / 10);
  putchar(x % 10 + '0');
}
inline void writeln(int x) {
  wrote(x);
  puts("");
}
const int maxn = 1000010;
struct data {
  int id, l, r;
};
struct dt {
  int x, v;
};
vector<data> g[maxn][2];
int n, m, ST[maxn][2];
bool operator<(data a, data b) { return a.l < b.l; }
bool operator<(dt a, dt b) { return a.v > b.v; }
priority_queue<dt> Q;
int dij() {
  Q.push((dt){1, 0});
  while (!Q.empty()) {
    int x = Q.top().x, now = Q.top().v, c = now & 1, st = now, in;
    Q.pop();
    if (x == n) return now;
    for (int i = ST[x][c]; i < g[x][c].size(); i++) {
      data to = g[x][c][i];
      if (to.l > now) break;
      ST[x][c] = i + 1;
      if (to.r < st) continue;
      now = max(now, to.r);
      now -= now - c & 1;
      in = max(st, to.l);
      in += in - c & 1;
      if ((in < to.r) && (in >= to.l)) Q.push((dt){to.id, in + 1});
    }
  }
  return -1;
}
int main() {
  n = read();
  m = read();
  for (int i = 1; i <= m; ++i) {
    int x = read(), y = read(), l = read(), r = read();
    g[x][0].push_back((data){y, l, r});
    g[y][0].push_back((data){x, l, r});
    g[x][1].push_back((data){y, l, r});
    g[y][1].push_back((data){x, l, r});
  }
  for (int i = 1; i <= n; ++i)
    for (int j = 0; j <= 1; ++j) sort(g[i][j].begin(), g[i][j].end());
  writeln(dij());
}
