#include <algorithm>
#include <array>
#include <assert.h>
#include <chrono>
#include <bitset>
#include <deque>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <numeric>
#include <random>
#include <queue>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<ld> vld;
typedef vector<vector<int>> vvi;
typedef vector<ll> vl;
typedef vector<vector<ll>> vvl;
typedef vector<vector<ld>> vvld;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector<pll> vpll;

#ifdef OLBOEB
mt19937 rnd(228 + 1488 + 238 + 24111997 % 322);
#else
mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

void print_time() {
#ifdef OLBOEB
    cout.flush();
    cerr << "\ntime: " << clock() * 1.0 / CLOCKS_PER_SEC << endl;
#endif
}

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define sz(x) ((ll)(x).size())
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()

template<class T1, class T2>
ostream& operator<< (ostream &out, pair<T1, T2> pair) { return out << "(" << pair.first << ", " << pair.second << ")";}
template<class T> ostream& operator<<(ostream& out, vector<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class T> ostream& operator<<(ostream& out, set<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class L, class R> ostream& operator<<(ostream& out, map<L, R> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }


const ll INF = 1e16;
struct SegmentTree {
    SegmentTree(ll n) : n(n), t(n * 2, +INF) {}
    SegmentTree(vl x) : n(x.size()), t(n * 2, +INF) {
        for (int i = 0; i < n; ++i) {
            t[i + n] = x[i];
        }
        build();
    }

    ll combine(ll a, ll b) { return min(a, b); }

    void build() {  // build the tree
        for (ll i = n - 1; i > 0; --i) t[i] = combine(t[i << 1], t[(i << 1) | 1]);
    }

    void modify(ll p, ll value) {  // set value at position p
        for (t[p += n] = value; p > 1; p >>= 1) t[p >> 1] = combine(t[p], t[p ^ 1]);
    }

    ll query(ll l, ll r) {  // [l, r)
        ll res = +INF;
        for (l += n, r += n; l < r; l >>= 1, r >>= 1) {
            if (l & 1) res = combine(res, t[l++]);
            if (r & 1) res = combine(res, t[--r]);
        }
        return res;
    }

    ll get(ll i) { return t[n + i]; }


    ll n;
    vl t;
};

void update(ll& x, ll y) { x = min(x, y); }

int main() {
    cout << fixed << setprecision(20);
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    ll n, m;
    cin >> n >> m;
    vector<vector<pll>> go(n + 1);
    for (ll i = 0; i < m; ++i) {
        ll l, r, c;
        cin >> l >> r >> c;
        --l, --r;
        go[r].pb({l, c});
    }

    SegmentTree dp(n + 1);
    dp.modify(0, 0);

    for (ll i = 1; i < n; ++i) {
        ll ans = dp.get(i);
        for (auto r : go[i]) {
            update(ans, dp.query(r.first, i) + r.second);
        }
        dp.modify(i, ans);
    }


    ll ans = dp.get(n - 1);
    cout << (ans == INF ? -1 : ans) << endl;


    print_time();
    return 0;
}


Measured memory_bytes: 7168