#include "bits/stdc++.h"
#define _overload3(_1,_2,_3,name,...)name
#define _rep(i,n)repi(i,0,n)
#define repi(i,a,b)for(int i=int(a),i##_len=(b);i<i##_len;++i)
#define MSVC_UNKO(x)x
#define rep(...)MSVC_UNKO(_overload3(__VA_ARGS__,repi,_rep,_rep)(__VA_ARGS__))
#define all(c)c.begin(),c.end()
#define write(x)cout<<(x)<<'\n'
using namespace std; typedef long long ll; template<class T>using vv = vector<vector<T>>;
template<class T>auto vvec(int n, int m, T v) { return vv<T>(n, vector<T>(m, v)); }
template<class T, class U>bool chmax(T& a, U&& b) { return a < b ? a = b, 1 : 0; }
template<class T, class U>bool chmin(T& a, U&& b) { return b < a ? a = b, 1 : 0; }
constexpr int INF = 1 << 29, MOD = int(1e9) + 7; constexpr ll LINF = 1LL << 60;
struct aaa { aaa() { cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(10); }; }aaaa;

template<typename T, class F, const T I>
struct SegmentTree {
    const F op = F();
    int n; vector<T> dat;
    void init(int n_) { n = 1; while (n < n_) n *= 2; dat.assign(n * 2, I); }
    void build(const vector<T>& v) {
        int n_ = v.size(); init(n_); for (int i = 0; i < n_; ++i) dat[n + i] = v[i];
        for (int i = n - 1; i; --i) dat[i] = op(dat[i * 2], dat[i * 2 + 1]);
    }
    void update(int k, T v) { dat[k += n] = v; while (k /= 2) dat[k] = op(dat[k * 2], dat[k * 2 + 1]); }
    T query(int a, int b) {
        T vl = I, vr = I;
        for (int l = a + n, r = b + n; l < r; l /= 2, r /= 2) { if (l & 1) vl = op(vl, dat[l++]); if (r & 1) vr = op(dat[--r], vr); }
        return op(vl, vr);
    }

private:
    template<class C> int find(int a, int b, C& check, int k, int l, int r) {
        if (!check(dat[k]) || r <= a || b <= l) return -1; else if (k >= n) return k - n;
        int m = (l + r) / 2; int vl = find(a, b, check, k * 2, l, m);
        if (~vl) return vl; else return find(a, b, check, k * 2 + 1, m, r);
    }
};

template<typename T = int> struct min_of { constexpr T operator ()(T& lhs, T& rhs) const { return min<T>(lhs, rhs); } };
extern constexpr ll identity = LINF;

int main() {
    int N, M;
    cin >> N >> M;
    vector<int> L(M), R(M), C(M);
    rep(i, M) {
        cin >> L[i] >> R[i] >> C[i];
        L[i]--;
        R[i]--;
    }

    vector<int> idx(M);
    iota(all(idx), 0);
    sort(all(idx), [&](int l, int r) { return R[l] < R[r]; });

    if (R[idx[M - 1]] != N - 1) {
        write(-1);
        return 0;
    }

    vector<pair<int, int>> LRi;
    rep(i, M) {
        LRi.emplace_back(L[i], i);
        LRi.emplace_back(R[i], i);
    }
    sort(all(LRi));

    if (LRi[0].first != 0) {
        write(-1);
        return 0;
    }

    vector<int> rngs;
    for (int i = 0, j; i < 2 * M; i = j) {
        for (j = i + 1; j < 2 * M; ++j) {
            if (LRi[j].first != LRi[i].first) break;
        }

        rngs.push_back(LRi[i].first);
    }

    SegmentTree<ll, min_of<ll>, identity> dp;
    dp.build(vector<ll>(rngs.size(), LINF));

    dp.update(0, 0);
    rep(i, M) {
        int l = lower_bound(all(rngs), L[idx[i]]) - rngs.begin();
        int r = lower_bound(all(rngs), R[idx[i]]) - rngs.begin();
        ll c = dp.query(l, r) + C[idx[i]];
        ll org = dp.query(r, r + 1);
        if (c < org) {
            dp.update(r, c);
       

    ll ans = dp.query(rngs.size() - 1, rngs.size());
    if (ans != LINF) {
        write(ans);
    }
    else {
        write(-1);
    }
}