#include <bits/stdc++.h>
using ll = long long;
using namespace std;
using P = pair<int, long>;
template <typename T>
class SegmentTree {
  int n;
  T def;
  vector<T> tree;
  function<T(T, T)> operation_f;
  function<T(int, T)> update_f;
  T _query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) return def;
    if (a <= l && r <= b) return tree[(size_t)k];
    T vl = _query(a, b, k * 2 + 1, l, (l + r) / 2),
      vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
    return operation_f(vl, vr);
  }

 public:
  SegmentTree(
      int _n, T _def, function<T(T, T)> _operation_f,
      function<T(int, T)> _update_f =
          [](int i, T x) {
            i++;
            return x;
          })
      : def(_def), operation_f(_operation_f), update_f(_update_f) {
    n = 1;
    while (n < _n) n <<= 1;
    tree = vector<T>((size_t)(2 * n - 1), def);
  }
  SegmentTree(
      int _n, T _def, string mode,
      function<T(int, T)> _update_f =
          [](int i, T x) {
            i++;
            return x;
          })
      : SegmentTree(_n, _def,
                    mode == "max"
                        ? [](T l, T r) { return max(l, r); }
                        : (mode == "min" ? [](T l, T r) { return min(l, r); }
                                         : [](T l, T r) { return l + r; }),
                    _update_f) {}
  SegmentTree(
      int _n, string mode,
      function<T(int, T)> _update_f =
          [](int i, T x) {
            i++;
            return x;
          })
      : SegmentTree(_n,
                    mode == "max"
                        ? numeric_limits<T>::lowest()
                        : (mode == "min" ? numeric_limits<T>::max() : 0),
                    mode, _update_f) {}
  template <typename ID>
  void update(ID i, T x) {
    T next_i = update_f((int)i, x);
    i += (ID)n - 1;
    tree[(size_t)i] = next_i;
    while (i > 0) {
      i = (i - 1) / 2;
      tree[(size_t)i] =
          operation_f(tree[(size_t)(i * 2 + 1)], tree[(size_t)(i * 2 + 2)]);
    }
  }
  template <typename ID1, typename ID2>
  T query(ID1 a, ID2 b) {
    return _query((int)a, (int)b, 0, 0, n);
  }
  void print_tree() {
    size_t next = 0, size = (size_t)(2 * n - 1);
    for (size_t i = 0; i < size; i++) {
      cout << tree[i];
      if (i == next) {
        cout << '\n';
        next = (next + 1) * 2;
      } else
        cout << string(size * 2 / (next + 2), ' ');
    }
  }
  typename vector<T>::iterator begin() { return tree.begin() + n - 1; }
  typename vector<T>::iterator end() { return tree.end(); }
  T operator[](int i) { return tree[(size_t)(i + n - 1)]; }
};
struct edge {
  int l, r;
  long c;
};
int main() {
  int n, m;
  cin >> n >> m;
  edge es[m];
  for (auto &ei : es) {
    cin >> ei.l >> ei.r >> ei.c;
    ei.l--;
    ei.r--;
  }
  sort(es, es + m, [](edge a, edge b) {
    if (a.l != b.l) return a.l < b.l;
    if (a.r != b.r) return a.r < b.r;
    return a.c < b.c;
  });
  SegmentTree<long> sgt(n, "min");
  sgt.update(0, 0);
  for (auto &ei : es) {
    long mi = sgt.query(ei.l, ei.r);
    if (mi + ei.c < sgt[ei.r]) sgt.update(ei.r, mi + ei.c);
  }
  cout << (sgt[n - 1] < numeric_limits<long>::max() ? sgt[n - 1] : -1) << '\n';
  return 0;
}
