#include <bits/stdc++.h>
template <typename T>
void read(T &);
template <typename T>
void write(const T &);
const int iinf = 2147483647;
const long long llinf = 9223372036854775807ll;
const int N = 500005;
const int M = 500005;
class Edge {
 public:
  int u, v, l, r;
  Edge(int u = 0, int v = 0, int l = 0, int r = 0) : u(u), v(v), l(l), r(r) {}
  friend bool operator<(const Edge &i, const Edge &j);
};
std::priority_queue<Edge> pq;
std::vector<Edge> E[N][2];
long long f[N][2];
int n, m;
int main() {
  read(n), read(m);
  if (n == 1) {
    puts("0");
    return 0;
  }
  for (int i = 1; i <= m; ++i) {
    int u, v, l, r;
    read(u), read(v), read(l), read(r);
    --r;
    int op = (r - l) & 1;
    pq.emplace(u, v, l, r - op), pq.emplace(v, u, l, r - op);
    pq.emplace(u, v, l + 1, r - !op), pq.emplace(v, u, l + 1, r - !op);
  }
  memset(f, -0x3f, sizeof(f));
  f[1][0] = 0;
  while (!pq.empty()) {
    auto [u, v, l, r] = pq.top();
    pq.pop();
    if (r < l) continue;
    bool op = l & 1;
    if (f[u][op] >= l) {
      if (v == n) {
        write(l + 1), putchar('\n');
        return 0;
      }
      if (r + 1 > f[v][!op]) {
        f[v][!op] = r + 1;
        for (auto [u1, v1, l1, r1] : E[v][!op]) {
          pq.emplace(u1, v1, l + 1, r1);
        }
        E[v][!op].clear();
      }
    } else {
      E[u][op].emplace_back(u, v, l, r);
    }
  }
  write(-1), putchar('\n');
  return 0;
}
bool operator<(const Edge &i, const Edge &j) { return i.l > j.l; }
template <typename T>
void read(T &Re) {
  T k = 0;
  char ch = getchar();
  int flag = 1;
  while (!(ch >= '0' && ch <= '9')) {
    if (ch == '-') flag = -1;
    ch = getchar();
  }
  while ((ch >= '0' && ch <= '9')) k = k * 10 + ch - '0', ch = getchar();
  Re = flag * k;
}
template <typename T>
void write(const T &Wr) {
  if (Wr < 0) {
    putchar('-'), write(-Wr);
  } else if (Wr < 10) {
    putchar(Wr + '0');
  } else {
    write(Wr / 10), putchar((Wr % 10) + '0');
  }
}
