#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
void d_err() { cerr << endl; }
template <typename H, typename... T>
void d_err(H h, T... t) {
  cerr << h << " ";
  d_err(t...);
}
template <typename T>
void print(T x) {
  cout << x << "\n";
}
long long INF = 1e16;
int inf = 1e9;
long long MOD = 1e9 + 7;
template <class T>
struct LazySegTree {
  using OP = function<T(T, T)>;
  using UP = function<void(T &, T)>;
  OP op;
  UP up_d, up_l;
  T ue_d, ue_l;
  int N;
  vector<T> dat, lazy;
  int get_n(int n) {
    int ret = 1;
    while (ret < n) ret <<= 1;
    return ret;
  }
  explicit LazySegTree(int n, const OP _op, const UP _up_d, const UP _up_l,
                       const T _ue_d, const T _ue_l)
      : op(_op), up_d(_up_d), up_l(_up_l), ue_d(_ue_d), ue_l(_ue_l) {
    N = get_n(n);
    dat.assign(N * 2 - 1, ue_d);
    lazy.assign(N * 2 - 1, ue_l);
  }
  void init(const T &v) {
    for (int i = (0); i < (N); ++i) dat[i + N - 1] = v;
    for (int i = N - 2; i >= 0; --i) {
      dat[i] = op(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }
  inline void evaluate(int k) {
    if (lazy[k] == ue_l) return;
    if (k < N - 1) {
      up_l(lazy[k * 2 + 1], lazy[k]);
      up_l(lazy[k * 2 + 2], lazy[k]);
    }
    up_d(dat[k], lazy[k]);
    lazy[k] = ue_l;
  }
  void update(int a, int b, const T &v, int k = 0, int l = 0, int r = -1) {
    evaluate(k);
    if (r < 0) r = N;
    if (r <= a || b <= l) return;
    if (a <= l && r <= b) {
      up_l(lazy[k], v);
      evaluate(k);
      return;
    }
    int mid = (l + r) / 2;
    update(a, b, v, k * 2 + 1, l, mid);
    update(a, b, v, k * 2 + 2, mid, r);
    dat[k] = op(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
  void update(int i, const T &v) { update(i, i + 1, v); }
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = N;
    if (r <= a || b <= l) return ue_d;
    evaluate(k);
    if (a <= l && r <= b) return dat[k];
    int mid = (l + r) / 2;
    T q1 = query(a, b, k * 2 + 1, l, mid);
    T q2 = query(a, b, k * 2 + 2, mid, r);
    return op(q1, q2);
  }
  void debug_() {}
};
int main() {
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(20);
  int n, m;
  cin >> n >> m;
  vector<pair<int, pair<int, long long>>> lrc(m);
  for (int i = (0); i < (m); ++i) {
    int l, r;
    long long c;
    cin >> l >> r >> c;
    l--;
    lrc[i] = make_pair(l, make_pair(r, c));
  }
  sort((lrc).begin(), (lrc).end());
  auto op = [](long long a, long long b) { return min(a, b); };
  auto up_d = [](long long &d, long long v) { d = min(d, v); };
  auto up_l = [](long long &l, long long v) { l = min(l, v); };
  LazySegTree<long long> st(n, op, up_d, up_l, INF, INF);
  st.update(0, 0);
  for (int i = (0); i < (m); ++i) {
    auto &p = lrc[i];
    int l, r;
    long long c;
    l = p.first, r = p.second.first, c = p.second.second;
    long long min_v = st.query(l, r);
    if (min_v >= INF) {
      print(-1);
      return 0;
    }
    st.update(l, r, min_v + c);
  }
  print(st.query(n - 1, n));
}
