#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using pll = pair<ll, ll>;
using vp = vector<pll>;
#define rep(i, n) for(ll i = 0; i < (n); i++)
#define repb(i, n) for(ll i = (n)-1; i >= 0; i--)
#define repr(i, a, b) for(ll i = (a); i < (b); i++)
#define reprb(i, a, b) for(ll i = (b)-1; i >= (a); i--)
#define ALL(a) (a).begin(), (a).end()
#define SZ(x) ((ll)(x).size())
const ll MOD = 1000000007;
const ll INF = 100000000000000000LL;
const ld EPS = 1e-12L;
const ld PI = 3.1415926535897932385L;
inline ll GCD(ll a, ll b){ return b?GCD(b, a % b):a; }
inline ll LCM(ll a, ll b){ return a/GCD(a, b)*b; }
inline ll powint(ull x, ll y){ ll r=1; while(y){ if(y&1) r*=x; x*=x; y>>=1; } return r; }
inline ll powmod(ll x, ll y, ll m = MOD){ ll r=1; while(y){ if(y&1) r*=x; x*=x; r%=m; x%=m; y>>=1; } return r; }
template<class S, class T>inline bool chmax(S &a, const T &b){ if(a<b) { a=b; return 1; } return 0; }
template<class S, class T>inline bool chmin(S &a, const T &b){ if(b<a) { a=b; return 1; } return 0; }
#ifdef OJ_LOCAL
#include "dump.hpp"
#else
#define dump(...) ((void)0)
#endif

template<typename T> struct Edge {
    int from, to;
    T cost;
    Edge(int from, int to, T cost): from(from), to(to), cost(cost) {}
    Edge(int from, int to): from(from), to(to), cost(1) {}
    bool operator<(Edge<T> &r) {
        return cost < r.cost;
    }
};
template<typename T>
ostream &operator<<(ostream &os, Edge<T> edge) {
    os << edge.from << " -> " << edge.to << " (" << edge.cost << ")";
    return os;
}

// グラフテンプレート(隣接リスト)
template<typename E = Edge<ll>> struct GraphL {
    // 頂点数、辺数
    int n, m;
    // 隣接リスト
    vector<vector<E>> adj;
    GraphL(int n)
        : n(n), m(0), adj(n) {}
    
    template<typename... Args>
    void add_edge(int from, int to, Args... args) {
        adj[from].emplace_back(from, to, args...);
        m++;
    }
};
template<typename E = Edge<ll>>
ostream &operator<<(ostream &os, GraphL<E> graph) {
    os << "V = " << graph.n << ", E = " << graph.m << "\n";
    for(const auto& ev: graph.adj) {
        for(const auto& e: ev) {
            os << e << "\n";
        }
    }
    return os;
}


template<typename E>
vector<ll> Dijkstra(GraphL<E> &graph, int start_node) {
    using P = pair<ll, int>;
    vector<ll> dist(graph.n, INF);
    dist[start_node] = 0;
    priority_queue<P, vector<P>, greater<P>> que;
    que.emplace(0, start_node);
    while(!que.empty()){
        P p = que.top();
        que.pop();
        ll v = p.second;
        if(dist[v] < p.first){
            continue;
        }
        for(auto&& e: graph.adj[v]){
            if(dist[e.to] > dist[v] + e.cost){
                dist[e.to] = dist[v] + e.cost;
                que.emplace(dist[e.to], e.to);
            }
        }
    }
    return dist;
}

// https://onlinejudge.u-aizu.ac.jp/solutions/problem/DSL_2_D/review/3635072/beet/C++14
template <typename E>
struct SegmentTree{
  using H = function<E(E,E)>;
  int n,height;
  H h;
  E ei;
  vector<E> laz;
  SegmentTree(H h,E ei):h(h),ei(ei){}  
  void init(int n_){
    n=1;height=0;
    while(n<n_) n<<=1,height++;
    laz.assign(2*n,ei);
  }
  inline void eval(int k){
    if(laz[k]==ei) return;
    laz[(k<<1)|0]=h(laz[(k<<1)|0],laz[k]);
    laz[(k<<1)|1]=h(laz[(k<<1)|1],laz[k]);
    laz[k]=ei;
  }
  inline void thrust(int k){
    for(int i=height;i;i--) eval(k>>i);
  }
  void update(int a,int b,E x){
    thrust(a+=n);
    thrust(b+=n-1);
    for(int l=a,r=b+1;l<r;l>>=1,r>>=1){
      if(l&1) laz[l]=h(laz[l],x),l++;
      if(r&1) --r,laz[r]=h(laz[r],x);
    }
  }
  E get_val(int a){
    thrust(a+=n);
    return laz[a];
  }
  void set_val(int a,E x){
    thrust(a+=n);
    laz[a]=x;
  }
};

using vpp = vector<pair<ll, pair<ll, ll>>>;

int main(){
    cin.tie(0); ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    ll n, m;
    cin >> n >> m;
    vll l(m), r(m), c(m);
    vpp ran;
    rep(i, m){
        cin >> l[i] >> r[i] >> c[i];
        ran.emplace_back(pair<ll, pll>(r[i], pll(l[i], c[i])));
    }
    sort(ALL(ran));
    auto h=[](ll a,ll b){return min(a, b);};
    SegmentTree<ll> seg(h, INF);
    seg.init(n+1);
    seg.update(1, 2, 0);
    rep(i, m){
        seg.update(ran[i].second.first, ran[i].first+1, seg.get_val(ran[i].second.first)+ran[i].second.second);
    }
    if(seg.get_val(n) < INF) cout << seg.get_val(n) << endl;
    else cout << -1 << endl;
    return 0;
}

Measured memory_bytes: 7408