#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int x = 0, f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar())
    if (c == '-') f = -1;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  return x * f;
}
const int MAXN = 1000010;
const int INF = 1e9;
int N, M;
int Node[MAXN << 1], Next[MAXN << 1], Root[MAXN + 1], cnt;
int L[MAXN << 1], R[MAXN << 1];
int T[MAXN << 1];
priority_queue<pair<int, int>, vector<pair<int, int> >,
               greater<pair<int, int> > >
    que, S[MAXN + 1];
inline void insert(int u, int v, int l, int r, int t) {
  if (l > r) return;
  Node[++cnt] = v;
  Next[cnt] = Root[u];
  Root[u] = cnt;
  T[cnt] = t;
  L[cnt] = l;
  R[cnt] = r;
  S[u].push(pair<int, int>(l, cnt));
}
int main() {
  N = read();
  M = read();
  for (int i = 1; i <= M; i++) {
    int u = read(), v = read(), l = read(), r = read();
    --r;
    insert(u, v + N, l + (l & 1), r - (r & 1), (r & 1));
    insert(v, u + N, l + (l & 1), r - (r & 1), (r & 1));
    insert(u + N, v, l + ((l & 1) ^ 1), r - ((r & 1) ^ 1), (r & 1) ^ 1);
    insert(v + N, u, l + ((l & 1) ^ 1), r - ((r & 1) ^ 1), (r & 1) ^ 1);
  }
  que.push(pair<int, int>(0, 1));
  while (!que.empty()) {
    pair<int, int> kt = que.top();
    int t = kt.first, k = kt.second;
    if (k == N || k == 2 * N) {
      printf("%d\n", t);
      return 0;
    }
    int last = t;
    while (!S[k].empty()) {
      pair<int, int> d = S[k].top();
      int x = d.second;
      if (L[x] > last) {
        break;
      }
      S[k].pop();
      if (R[x] < t) continue;
      que.push(pair<int, int>(max(L[x], t) + 1, Node[x]));
      last = max(last, R[x] + T[x] * 2);
    }
    que.pop();
  }
  puts("-1");
  return 0;
}
