/* ---------- STL Libraries ---------- */
// IO library
#include <cstdio>

#include <fstream>
#include <iomanip>
#include <ios>
#include <iostream>

// algorithm library
#include <algorithm>

#include <cmath>
#include <numeric>
#include <random>
#include <cstring>

// container library
#include <array>
#include <bitset>
#include <deque>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <string>
#include <tuple>
#include <vector>
#include <stack>

// type
#include <cstdint>
#include <climits>

/* ---------- Namespace ---------- */
using namespace std;

/* ---------- Type ---------- */
using ll = long long;
#define int ll
#define P pair<ll, ll>

/* ---------- Constants  */
const double PI = 3.141592653589793238462643383279;
const ll MOD = 1e9 + 7;
const int INF = 1LL << 55;

/* v-v-v-v-v-v-v-v-v Main Part v-v-v-v-v-v-v-v-v */

struct RangeMin {
private:
    int n;
    vector<int> node;

public:
    RangeMin(vector<int> v) {
        size_t sz = v.size();
        n = 1;
        while (n < sz) n *= 2;
        node.resize(2 * n - 1, INF);
        for (int i = 0; i < sz; i++) node[i + n - 1] = v[i];
        for (int i = n - 2; i >= 0; i--) node[i] = min(node[2 * i + 1], node[2 * i + 2]);
    }

    void update(int x, int val) {
        x += (n - 1);
        node[x] = val;
        while (x > 0) {
            x = (x - 1) / 2;
            node[x] = min(node[2 * x + 1], node[2 * x + 2]);
        }
    }

    int getmin(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = n;
        if (r <= a || b <= l) return INF;
        if (a <= l && r <= b) return node[k];

        int vl = getmin(a, b, 2 * k + 1, l, (l + r) / 2);
        int vr = getmin(a, b, 2 * k + 2, (l + r) / 2, r);
        return min(vl, vr);
    }
};

// Range Maximum Query
struct RangeMax {
private:
    int n;

public:
    vector<int> node;

    RangeMax(vector<int> v) {
        size_t sz = v.size();
        n = 1;
        while (n < sz) n *= 2;
        node.resize(2 * n - 1, INT_MIN);
        for (int i = 0; i < sz; i++) node[i + n - 1] = v[i];
        for (int i = n - 2; i >= 0; i--) node[i] = max(node[2 * i + 1], node[2 * i + 2]);
    }

    void update(int x, int val) {
        x += (n - 1);
        node[x] = val;
        while (x > 0) {
            x = (x - 1) / 2;
            node[x] = max(node[2 * x + 1], node[2 * x + 2]);
        }
    }

    int getmax(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = n;
        if (r <= a || b <= l) return INT_MIN;
        if (a <= l && r <= b) return node[k];

        int vl = getmax(a, b, 2 * k + 1, l, (l + r) / 2);
        int vr = getmax(a, b, 2 * k + 2, (l + r) / 2, r);
        return max(vl, vr);
    }
};

signed main() {
    int N, M;
    cin >> N >> M;
    vector<tuple<int, int ,int>> ranges(M);
    for (int i = 0; i < M; i++) {
        int l, r, c;
        cin >> l >> r >> c;
        l--; r--;
        ranges[i] = make_tuple(l, r, c);
    }

    sort(ranges.begin(), ranges.end());
    RangeMin seg(vector<int>(N, INF));

    vector<int> dp(N, INF);
    dp[0] = 0;
    seg.update(0, 0);

    for (int i = 0; i < M; i++) {
        int l = get<0>(ranges[i]);
        int r = get<1>(ranges[i]);
        int c = get<2>(ranges[i]);

        dp[r] = min(dp[r], seg.getmin(l, r + 1) + c);
        seg.update(r, dp[r]);
    }

    if (dp[N-1] >= INF) {
        cout << -1 << endl;
    } else {
        cout << dp[N-1] << endl;
    }

    return 0;
}

Measured memory_bytes: 5376