#include <bits/stdc++.h>
using namespace std;
const int N = 500010;
vector<int> v[N][2];
struct point {
  int v, l, r;
  point() {}
  point(int v, int l, int r) : v(v), l(l), r(r) {}
} e[N << 2];
int cnt;
bool cmp(int first, int second) { return e[first].l > e[second].l; }
priority_queue<pair<int, int> > pq;
int dis[N << 2];
int dij(int n) {
  memset(dis, -1, sizeof(dis));
  if (n == 1) return 0;
  for (int i = 0; i < v[1][0].size(); i++) {
    int first = v[1][0][i];
    if (e[first].l == 0) pq.push(make_pair(0, first)), dis[first] = 0;
  }
  while (!pq.empty()) {
    int l = -pq.top().first, u = pq.top().second;
    pq.pop();
    if (dis[u] != l) continue;
    if (e[u].v == n) return l + 1;
    l++;
    int first = l & 1;
    int r = e[u].r;
    if (r % 2 != first) r++;
    int to = e[u].v;
    while (!v[to][first].empty()) {
      int second = v[to][first].back();
      if (e[second].l > r) break;
      v[to][first].pop_back();
      if (e[second].r < l) {
        continue;
      }
      int cost = max(e[second].l, l);
      if (cost > r) break;
      if (dis[second] == -1 || cost < dis[second]) {
        dis[second] = cost;
        pq.push(make_pair(-cost, second));
      }
    }
  }
  return -1;
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  int a, b, l, r;
  while (m--) {
    scanf("%d%d%d%d", &a, &b, &l, &r);
    r--;
    for (int i = 0; i < 2; i++) {
      int first = l, second = r;
      if (first % 2 != i) first++;
      if (second % 2 != i) second--;
      if (first > second) continue;
      e[cnt++] = point(b, first, second);
      v[a][i].push_back(cnt - 1);
      e[cnt++] = point(a, first, second);
      v[b][i].push_back(cnt - 1);
    }
  }
  for (int i = 1; i <= n; i++)
    for (int j = 0; j < 2; j++) sort(v[i][j].begin(), v[i][j].end(), cmp);
  int ans = dij(n);
  printf("%d\n", ans);
  return 0;
}
