#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
inline int read() {
  int s = 0;
  char ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) s = s * 10 + ch - '0', ch = getchar();
  return s;
}
int n, m;
struct node {
  int x, y, l, r;
  bool operator<(const node& b) const { return l > b.l; }
};
priority_queue<node> q;
int f[N][2];
vector<pair<int, int> > G[N][2];
int main() {
  n = read(), m = read();
  if (n == 1) {
    puts("0");
    return 0;
  }
  for (int i = 1; i <= m; i++) {
    int x = read(), y = read(), l = read(), r = read() - 1;
    int t = (r - l) & 1;
    q.push({x, y, l, r - t});
    q.push({x, y, l + 1, r - (1 - t)});
    q.push({y, x, l, r - t});
    q.push({y, x, l + 1, r - (1 - t)});
  }
  memset(f, -1, sizeof(f));
  f[1][0] = 0;
  while (!q.empty()) {
    node u = q.top();
    q.pop();
    if (u.l > u.r) continue;
    if (f[u.x][u.l & 1] >= u.l) {
      if (u.y == n) {
        printf("%d", u.l + 1);
        return 0;
      }
      u.l++, u.r++;
      f[u.y][u.l & 1] = max(f[u.y][u.l & 1], u.r);
      for (auto p : G[u.y][u.l & 1]) q.push({u.y, p.first, u.l, p.second});
      G[u.y][u.l & 1].clear();
    } else
      G[u.x][u.l & 1].push_back({u.y, u.r});
  }
  puts("-1");
  return 0;
}
