#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long; 
using pii =  pair<int, int>;
using pll =  pair<long long, long long>;
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define all(x) (x).begin(),(x).end()
constexpr char ln =  '\n';

template<typename T>
struct edge {
    int src,to;
    T cost;
    int id;

    edge(){}
    edge(int to, T cost) : src(-1), to(to), cost(cost), id(-1) {}
    edge(int src, int to, T cost) : src(src), to(to), cost(cost), id(-1) {}
    edge(int src, int to, T cost, int id) : src(src), to(to), cost(cost), id(id) {}
    bool operator<(const edge &e) const {return cost < e.cost;}
};

/////////////////////////////////////////////////////////////////////////////////

template<typename T>
struct RangeEdge {
    vector<vector<edge<T>>> G;
    int N,sz,to,from;

    RangeEdge() {}
    RangeEdge(int N) : N(N) {
        sz = 1;
        while (sz < N) sz <<= 1;
        to = N;
        from = N+sz*2;
        G.resize(N+sz*4);
        for (int i = 0; i < N; ++i) {
            G[to+i+sz].emplace_back(i,0);
            G[i].emplace_back(from+i+sz,0);
        }
        for (int i = 1; i < sz; ++i) {
            G[to+i].emplace_back(to+(i<<1|0),0);
            G[to+i].emplace_back(to+(i<<1|1),0);
            G[from+(i<<1|0)].emplace_back(from+i,0);
            G[from+(i<<1|1)].emplace_back(from+i,0);
        }
    }

private:
    void update(int l, int r, int v, int flag) {
        l += sz; r += sz;
        while (l < r) {
            if (l & 1) {
                if (flag) G[v].emplace_back(to+l,0);
                else G[from+l].emplace_back(v,0);
                ++l;
            }
            l >>= 1;
            if (r & 1) {
                --r;
                if (flag) G[v].emplace_back(to+r,0);
                else G[from+r].emplace_back(v,0);
            }
            r >>= 1; 
        }
    }

public:

    void addedge(int fromL, int fromR, int toL, int toR, T cost) {
        if (fromL >= fromR or toL >= toR) return;
        int M = G.size();
        G.emplace_back();
        G.emplace_back();
        G[M].emplace_back(M+1,cost);
        update(fromL,fromR,M,0);
        update(toL,toR,M+1,1);
    }
};

//////////////////////////////////////////////////////////////////////////////////

template<typename T>
vector<T> Dijkstra(vector<vector<edge<T>>> &G, int s, T inf) {
    vector<T> dist(G.size(),inf);

    using Pi = pair<T, int>;
    priority_queue<Pi, vector<Pi>, greater<Pi>> pq;
    dist[s] = 0;
    pq.emplace(dist[s],s);
    while (!pq.empty()) {
        T d; int v;
        tie(d,v) = pq.top(); pq.pop();
        if (d > dist[v]) continue;
        for (auto &e : G[v]) {
            if (dist[e.to] > dist[v] + e.cost) {
                dist[e.to] = dist[v] + e.cost;
                pq.emplace(dist[e.to],e.to);
            }
        }
    }

    return dist;
}

int main() {
    ios::sync_with_stdio(false); cin.tie(nullptr);
    int N,M; cin >> N >> M;
    RangeEdge<ll> RE(N);
    rep(i,M) {
        int u,v,w; cin >> u >> v >> w;
        --u;
        RE.addedge(u,v,u,v,w);
    }

    auto dist = Dijkstra<ll>(RE.G,0,1e18);
    cout << (dist[N-1] == 1e18 ? -1 : dist[N-1]) << ln;
}

/*
  verified on 2020/05/26
*/

Measured memory_bytes: 145644