#include <iostream>
#include <iomanip>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <functional>
#include <climits>

using namespace std;
using ll = long long;

#define rep(i, n)      for (int i = 0; i < (n); i++)
#define repr(i, n)     for (int i = (n) - 1; i >= 0; i--)
#define repe(i, l, r)  for (int i = (l); i < (r); i++)
#define reper(i, l, r) for (int i = (r) - 1; i >= (l); i--)
#define repi(i, l, r)  for (int i = (l); i <= (r); i++)
#define repir(i, l, r) for (int i = (r); i >= (l); i--)
#define range(a) a.begin(), a.end()
void init_io() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(15); }

template<class Vec, class Mat, class VV, class MV, class MM>
struct lazy_segtree {
  int N;
  vector<Vec> vec;
  vector<Mat> mat;
  Vec vec_ident;
  Mat mat_ident;

  VV vec_vec;
  MV mat_vec;
  MM mat_mat;

  lazy_segtree(
    int n,
    function<Vec(int)> init,
    Vec vec_ident_,
    Mat mat_ident_,
    VV vec_vec_,
    MV mat_vec_,
    MM mat_mat_) :
    vec_ident(vec_ident_),
    mat_ident(mat_ident_),
    vec_vec(vec_vec_),
    mat_vec(mat_vec_),
    mat_mat(mat_mat_)
   {
    N = 1;
    while (N < n) N *= 2;
    vec.resize(N * 2, vec_ident);
    mat.resize(N * 2, mat_ident);
    for (int i = 0; i < n; i++) {
      vec[i + N] = init(i);
    }
    for (int i = N - 1; i >= 1; i--) {
      pull(i);
    }
  }

  void apply(int k, Mat v) {
    mat[k] = mat_mat(v, mat[k]);
    vec[k] = mat_vec(v, vec[k]);
  }

  void push(int k) {
    apply(k << 1 | 0, mat[k]);
    apply(k << 1 | 1, mat[k]);
    mat[k] = mat_ident;
  }

  void pull(int k) {
    vec[k] = vec_vec(vec[k << 1], vec[k << 1 | 1]);
  }

  void update(int a, int b, Mat v, int k, int l, int r) {
    if (r <= a || b <= l) return;
    if (a <= l && r <= b) {
      apply(k, v);
      return;
    }
    push(k);
    update(a, b, v, k << 1 | 0, l, l + r >> 1);
    update(a, b, v, k << 1 | 1, l + r >> 1, r);
    pull(k);
  }

  void update(int a, int b, Mat v) {
    update(a, b, v, 1, 0, N);
  }

  Vec query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) return vec_ident;
    if (a <= l && r <= b) return vec[k];
    push(k);
    Vec vl = query(a, b, k << 1 | 0, l, l + r >> 1);
    Vec vr = query(a, b, k << 1 | 1, l + r >> 1, r);
    return vec_vec(vl, vr);
  }

  Vec query(int a, int b) {
    return query(a, b, 1, 0, N);
  }
};

template<class Vec, class Mat, class VV, class MV, class MM>
lazy_segtree<Vec, Mat, VV, MV, MM> create_lazy_segtree(
  int n,
  function<Vec(int)> init,
  Vec vec_ident_,
  Mat mat_ident_,
  VV vec_vec_,
  MV mat_vec_,
  MM mat_mat_) {
  return lazy_segtree<Vec, Mat, VV, MV, MM>(n, init, vec_ident_, mat_ident_, vec_vec_, mat_vec_, mat_mat_);
}

auto lz_assign_plus(int n, function<pair<long long, long long>(int)> init) {
  using vec = pair<long long, long long>;
  using mat = long long;
  return create_lazy_segtree<vec, mat>(
    n,
    init,
    {0LL, 0LL},
    LLONG_MAX,
    [](vec a, vec b) -> vec { return {a.first + b.first, a.second + b.second}; },
    [](mat a, vec b) -> vec { return a == LLONG_MAX ? b : vec(a * b.second, b.second); },
    [](mat a, mat b) -> mat { return a == LLONG_MAX ? b : a; });
}

auto lz_assign_min(int n, function<long long(int)> init) {
  using vec = long long;
  using mat = long long;
  return create_lazy_segtree(
    n,
    init,
    LLONG_MAX,
    LLONG_MAX,
    [](vec a, vec b) -> vec { return min(a, b); },
    [](mat a, vec b) -> vec { return min(a, b); },
    [](mat a, mat b) -> mat { return min(a, b); });
}

auto lz_assign_max(int n, function<long long(int)> init) {
  using vec = long long;
  using mat = long long;
  return create_lazy_segtree(
    n,
    init,
    LLONG_MIN,
    LLONG_MAX,
    [](vec a, vec b) -> vec { return max(a, b); },
    [](mat a, vec b) -> vec { return a == LLONG_MAX ? b : a; },
    [](mat a, mat b) -> mat { return a == LLONG_MAX ? b : a; });
}

auto lz_plus_min(int n, function<long long(int)> init) {
  using vec = long long;
  using mat = long long;
  return create_lazy_segtree(
    n,
    init,
    LLONG_MAX,
    0LL,
    [](vec a, vec b) { return min(a, b); },
    [](mat a, vec b) { return a + b; },
    [](mat a, mat b) { return a + b; });
}

auto lz_plus_max(int n, function<long long(int)> init) {
  using vec = long long;
  using mat = long long;
  return create_lazy_segtree(
    n,
    init,
    LLONG_MIN,
    0LL,
    [](vec a, vec b) { return max(a, b); },
    [](mat a, vec b) { return a + b; },
    [](mat a, mat b) { return a + b; });
}



int main() { init_io();
  int N, M; cin >> N >> M;
  vector<vector<pair<int, int>>> G(N);
  rep(i, M) {
    int l, r, c; cin >> l >> r >> c; l--;
    G[l].emplace_back(r, c);
  }
  constexpr ll INF = 1e18;
  auto seg = lz_assign_min(N, [](int i) -> ll {
    if (i == 0) return 0;
    return INF;
  });
  rep(i, N) {
    ll curr = seg.query(i, i + 1);
    for (auto p : G[i]) {
      seg.update(i + 1, p.first, curr + p.second);
    }
  }
  ll ans = seg.query(N - 1, N);
  if (ans >= INF) {
    cout << -1 << endl;
  } else {
    cout << seg.query(N - 1, N) << endl;
  }
}


Measured memory_bytes: 9728