#include <bits/stdc++.h>
using namespace std;
#define int long long

// T0: 元の配列のモノイド
// T1: T0に対する作用素モノイド
template <class T0, class T1>
class BaseSegmentTree {
    // k番目のノードにのlazyを伝搬
    void eval(int k, int len) {
        // 定数倍高速化
        if (lazy[k] == u1) return;
        // len個分のlazy[k]を評価
        node[k] = g(node[k], p(lazy[k], len));
        if (k < N - 1) {
            // 最下段でなければ下のlazyに伝搬
            lazy[2 * k + 1] = f1(lazy[2 * k + 1], lazy[k]);
            lazy[2 * k + 2] = f1(lazy[2 * k + 2], lazy[k]);
        }
        lazy[k] = u1;
    }
    // k番目のノード[l, r)について、[a, b)の範囲内にxを作用
    void update(int a, int b, T1 x, int k, int l, int r) {
        eval(k, r - l);
        if (b <= l || r <= a) return;
        if (a <= l && r <= b) {
            lazy[k] = f1(lazy[k], x);
            eval(k, r - l);
        } else {
            update(a, b, x, 2 * k + 1, l, (l + r) / 2);
            update(a, b, x, 2 * k + 2, (l + r) / 2, r);
            node[k] = f0(node[2 * k + 1], node[2 * k + 2]);
        }
    }
    // k番目のノード[l, r)について、[a, b)のクエリを求める
    T0 query(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) return u0;
        eval(k, r - l);
        if (a <= l && r <= b) return node[k];
        T0 vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
        T0 vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
        return f0(vl, vr);
    }

public:
    int sz;  // 元の配列のサイズ
    int N;
    vector<T0> node;
    vector<T1> lazy;
    // T0上の演算、単位元
    virtual T0 f0(T0, T0) = 0;
    const T0 u0;
    // T1上の演算、単位元
    virtual T1 f1(T1, T1) = 0;
    const T1 u1;
    // T0に対するT1の作用
    virtual T0 g(T0, T1) = 0;
    // 多数のt1(T1)に対するf1の合成
    virtual T1 p(T1, int) = 0;

    BaseSegmentTree(T0 u0, T1 u1) : u0(u0), u1(u1) {}
    void set_by_vector(const vector<T0> &a) {
        sz = a.size();
        for (N = 1; N < sz; N *= 2)
            ;
        node.resize(2 * N - 1, u0);
        lazy.resize(2 * N - 1, u1);
        for (int i = 0; i < sz; i++) node[N - 1 + i] = a[i];
        for (int i = N - 2; i >= 0; i--) node[i] = f0(node[2 * i + 1], node[2 * i + 2]);
    }
    void set_by_unit(int n) {
        sz = n;
        for (N = 1; N < sz; N *= 2)
            ;
        node.resize(2 * N - 1, u0);
        lazy.resize(2 * N - 1, u1);
    }
    // [a, b)にxを作用
    void update(int a, int b, T1 x) {
        assert(0 <= a && a < b && b <= sz);
        update(a, b, x, 0, 0, N);
    }
    void update(int a, T1 x) { update(a, a + 1, x); }
    // [a, b)
    T0 query(int a, int b) { return query(a, b, 0, 0, N); }
    T0 query(int a) { return query(a, a + 1); }
};

template <class T0, class T1>
struct MinUpdateQuery : public BaseSegmentTree<T0, T1> {
    using BaseSegmentTree<T0, T1>::BaseSegmentTree;
    static constexpr T0 _u0 = numeric_limits<T0>::max();
    static constexpr T1 _u1 = numeric_limits<T1>::min();
    MinUpdateQuery() : MinUpdateQuery(_u0, _u1) {}
    T0 f0(T0 x, T0 y) override { return min(x, y); }
    T1 f1(T1 x, T1 y) override { return y == _u1 ? x : y; }
    T0 g(T0 x, T1 y) override { return y == _u1 ? x : y; }
    T1 p(T1 x, int len) override { return x; }
};

struct Range {
    int l, r, c;
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, m;
    cin >> n >> m;
    vector<Range> as;
    for (int i = 0; i < m; i++) {
        int l, r, c;
        cin >> l >> r >> c;
        l--;
        as.push_back((Range){l, r, c});
    }
    sort(as.begin(), as.end(), [](auto &a, auto &b) { return a.l == b.l ? a.r > b.r : a.l < b.l; });

    MinUpdateQuery<int, int> seg;
    seg.set_by_vector(vector<int>(n, 1e18));
    seg.update(0, 0);

    for (int i = 0; i < m; i++) {
        int l = as[i].l, r = as[i].r, c = as[i].c;
        int x = seg.query(l) + c;
        // R: 初めてxより大きくなる座標
        if (seg.query(r - 1) <= x) continue;
        int L = l, R = r;
        while (L < R - 1) {
            int M = (L + R) / 2;
            if (seg.query(M) <= x)
                L = M;
            else
                R = M;
        }
        seg.update(R, r, x);
    }

    int ans = seg.query(n - 1);
    if (ans == 1e18) {
        cout << -1 << endl;
    } else {
        cout << ans << endl;
    }
}


Measured memory_bytes: 8176