#include <iostream>
#include <array>
#include <algorithm>
#include <vector>
#include <bitset>
#include <set>
#include <unordered_set>
#include <cmath>
#include <complex>
#include <deque>
#include <iterator>
#include <numeric>
#include <map>
#include <unordered_map>
#include <queue>
#include <stack>
#include <string>
#include <tuple>
#include <utility>
#include <limits>
#include <iomanip>
#include <functional>
#include <cassert>
// #include <atcoder/all>
using namespace std;

using ll=long long;
template<class T> using V = vector<T>;
template<class T, class U> using P = pair<T, U>;
using vll = V<ll>;
using vvll = V<vll>;
#define ALL(v) v.begin(),v.end()
template < class T > inline bool chmax(T& a, T b) {if (a < b) { a=b; return true; } return false; }
template < class T > inline bool chmin(T& a, T b) {if (a > b) { a=b; return true; } return false; }
#define DEBUG_VLL(vec) for(int sz=0;sz<int(vec.size());sz++) std::cerr<<vec[sz]<<(sz==vec.size()-1?'\n':' ');

const long long MOD = 1000000007;
const long long HIGHINF = (long long)1e18;
const int INF = (int)1e9;

template <typename T>
struct RangeGraph {
    int n;
    struct edge { int to; T weight; };
    std::vector< std::vector<edge> > graph;

    RangeGraph(int n): n(n), graph(4 * n) {
        for (int i = 1; i < n; i++) {
            int cl = i << 1 | 0, cr = i << 1 | 1;
            graph[i].push_back({cl, 0});
            graph[i].push_back({cr, 0});
            graph[cl + 2 * n].push_back({i + 2 * n, 0});
            graph[cr + 2 * n].push_back({i + 2 * n, 0});
        }
        for (int i = n; i < 2 * n; i++) graph[i].push_back({i + 2 * n, 0});
    }

    // from [l1, r1) to [l2, r2)
    void add_edge(int l1, int r1, int l2, int r2, T w) {
        int idx = graph.size();
        for (l1 += n, r1 += n; l1 < r1; l1 >>= 1, r1 >>= 1) {
            if (l1 & 1) graph[l1 + 2 * n].push_back({idx, 0}), l1++;
            if (r1 & 1) --r1, graph[r1 + 2 * n].push_back({idx, 0});
        }
        std::vector<edge> node;
        for (l2 += n, r2 += n; l2 < r2; l2 >>= 1, r2 >>= 1) {
            if (l2 & 1) node.push_back({l2++, w});
            if (r2 & 1) node.push_back({--r2, w});
        }
        graph.emplace_back(node);
    }

    vector<T> dijkstra(int s) {
        s += n;
        std::vector<T> dist(graph.size(), std::numeric_limits<T>::max());
        dist[s] = 0;
        using PI = std::pair<T, int>;
        std::priority_queue<PI, std::vector<PI>, greater<PI> > que;
        que.emplace(0, s);
        while (!que.empty()) {
            PI p = que.top();
            que.pop();
            int v = p.second;
            if (dist[v] < p.first) continue;
            for (edge& e: graph[v]) {
                if (dist[e.to] > dist[v] + e.weight) {
                    dist[e.to] = dist[v] + e.weight;
                    que.emplace(dist[e.to], e.to);
                }
            }
        }
        std::vector<T> res(dist.begin() + n, dist.begin() + 2 * n);
        return res;
    }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n, m; cin >> n >> m;
    RangeGraph<ll> rg(n);
    for (int i = 0; i < m; i++) {
        ll l, r, c; cin >> l >> r >> c;
        l--;
        rg.add_edge(l, r, l, r, c);
    }
    ll ans = rg.dijkstra(0).back();
    if (ans == numeric_limits<ll>::max()) cout << -1 << '\n';
    else cout << ans << '\n';
    return 0;
}


Measured memory_bytes: 89464