#include <bits/stdc++.h>
using namespace std;
class XY {
 public:
  long long x, y;
  XY() { x = y = 0; }
  XY(long long u, long long v) {
    x = u;
    y = v;
  }
};
template <typename T1, typename T2>
void chmin(T1 &first, T2 second) {
  if (first > second) first = second;
}
template <typename T1, typename T2>
void chmax(T1 &first, T2 second) {
  if (first < second) first = second;
}
template <typename T1, typename T2>
long long mypow(T1 first, T2 n) {
  if (n == 0) return 1;
  if (n == 1) return first;
  if (n % 2) return first * mypow(first, n - 1);
  long long tmp = mypow(first, n / 2);
  return tmp * tmp;
}
template <typename T>
int BS(vector<T> &V, int left, int right, T key) {
  int mid = (left + right) / 2;
  if (V[mid] <= key)
    left = mid;
  else
    right = mid;
  if (right - mid == 1)
    return left;
  else
    return BS(V, left, right, key);
}
long long comb(long long n, long long r) {
  long long res = 1;
  for (int i = 0; i < r; i++) {
    res *= n - i;
    res /= i + 1;
  }
  return res;
}
template <typename T>
T euclid(T first, T second) {
  if (second == 0)
    return first;
  else
    return euclid(second, first % second);
}
vector<long long> fact((100000), 0), fact_inv((100000), 0);
long long pow_mod(long long first, long long second) {
  long long res = 1;
  while (second > 0) {
    if (second & 1) res = res * first % (1000000007);
    first = first * first % (1000000007);
    second >>= 1;
  }
  return res;
}
void prepare_comb_mod(long long n) {
  fact[0] = 1LL;
  for (long long i = 0; i < n; i++)
    fact[i + 1] = fact[i] * (i + 1) % (1000000007);
  fact_inv[n] = pow_mod(fact[n], (1000000007) - 2);
  for (long long i = n - 1; i >= 0; i--)
    fact_inv[i] = fact_inv[i + 1] * (i + 1) % (1000000007);
}
long long comb_mod(long long n, long long r) {
  return (fact[n] * fact_inv[r]) % (1000000007) * fact_inv[n - r] %
         (1000000007);
}
template <class T>
struct UFT {
  vector<int> par;
  vector<int> rank;
  vector<T> diff_weight;
  UFT(int n = 1, T w = 0) { init(n, w); }
  void init(int n = 1, T w = 0) {
    par.resize(n);
    rank.resize(n);
    diff_weight.resize(n);
    for (int i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 0;
      diff_weight[i] = w;
    }
  }
  int root(int x) {
    if (par[x] == x) {
      return x;
    } else {
      int r = root(par[x]);
      diff_weight[x] += diff_weight[par[x]];
      return par[x] = r;
    }
  }
  bool unite(int x, int y, int w = 0) {
    w += weight(x);
    w -= weight(y);
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (rank[x] < rank[y]) {
      par[x] = y;
      diff_weight[x] = -w;
    } else {
      par[y] = x;
      diff_weight[y] = w;
      if (rank[x] == rank[y]) rank[x]++;
    }
    return true;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  T weight(int x) {
    root(x);
    return diff_weight[x];
  }
  T diff(int x, int y) { return weight(y) - weight(x); }
};
template <typename Monoid>
struct SegmentTree {
  using F = function<Monoid(Monoid, Monoid)>;
  int sz;
  vector<Monoid> seg;
  const F f;
  const Monoid M1;
  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while (sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }
  void set(int k, const Monoid &x) { seg[k + sz] = x; }
  void build() {
    for (int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }
  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }
  Monoid query(int first, int second) {
    Monoid L = M1, R = M1;
    for (first += sz, second += sz; first < second; first >>= 1, second >>= 1) {
      if (first & 1) L = f(L, seg[first++]);
      if (second & 1) R = f(seg[--second], R);
    }
    return f(L, R);
  }
  Monoid operator[](const int &k) const { return seg[k + sz]; }
  template <typename C>
  int find_subtree(int first, const C &check, Monoid &M, bool type) {
    while (first < sz) {
      Monoid nxt =
          type ? f(seg[2 * first + type], M) : f(M, seg[2 * first + type]);
      if (check(nxt))
        first = 2 * first + type;
      else
        M = nxt, first = 2 * first + 1 - type;
    }
    return first - sz;
  }
  template <typename C>
  int find_first(int first, const C &check) {
    Monoid L = M1;
    if (first <= 0) {
      if (check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    int second = sz;
    for (first += sz, second += sz; first < second; first >>= 1, second >>= 1) {
      if (first & 1) {
        Monoid nxt = f(L, seg[first]);
        if (check(nxt)) return find_subtree(first, check, L, false);
        L = nxt;
        ++first;
      }
    }
    return -1;
  }
  template <typename C>
  int find_last(int second, const C &check) {
    Monoid R = M1;
    if (second >= sz) {
      if (check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    int first = sz;
    for (second += sz; first < second; first >>= 1, second >>= 1) {
      if (second & 1) {
        Monoid nxt = f(seg[--second], R);
        if (check(nxt)) return find_subtree(second, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};
void Main() {
  int N, M;
  cin >> N >> M;
  vector<vector<pair<int, int>>> P(N);
  for (int i = 0; i < M; i++) {
    int l, r, c;
    cin >> l >> r >> c;
    l--;
    r--;
    P[r].push_back(pair<int, int>(l, c));
  }
  vector<long long> dp(N, (1000000000));
  SegmentTree<long long> seg(
      N, [](long long first, long long second) { return min(first, second); },
      (1000000000));
  seg.update(0, 0);
  dp[0] = 0;
  for (int i = 1; i < N; i++) {
    for (int j = 0; j < P[i].size(); j++) {
      chmin(dp[i], seg.query(P[i][j].first, i + 1) + P[i][j].second);
      seg.update(i, dp[i]);
    }
  }
  if (dp[N - 1] == (1000000000))
    cout << -1 << endl;
  else
    cout << dp[N - 1] << endl;
}
int main() {
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout << std::fixed << std::setprecision(15);
  Main();
}
