#include <iostream>
#include <vector>
#include <queue>
#define REP(i,n) for(int i=0;i<n;i++)

struct edge{
    int to;
    long long cost;
};

using namespace std;

//ダイクストラで多用する型
typedef pair<long long, int> P;//(その頂点までの距離,頂点)として使う。

vector<edge> G[100000];//頂点iから出る辺の配列G[i]の配列。
int dist[100000];//特定の頂点から各頂点への距離が格納される。
bool used[100000];//dijkstra実行中に、頂点iまでの距離を確定したかどうかを持つ。

void dijkstra(int v){//vは始点。
    //以下のリンクでpriority_queueの使い方を参照
    //http://shirokurostone.hatenablog.com/entry/20110522/1306052844
    priority_queue<P, vector<P>, greater<P>> que;
    que.push(P(1, v));
    while(!que.empty()){
        P top = que.top();
        que.pop();
        int u = top.second;
        long long d = top.first;
        //cout << u << ' ' << d << endl;
        if(used[u]) continue;
        dist[u] = d;
        used[u] = true;
        for(int i = 0; i < G[u].size(); i++){
            if(!used[G[u][i].to]){
                que.push(P(d+G[u][i].cost, G[u][i].to));
                //cout << G[u][i].to << ' ' <<  d+G[u][i].cost << endl;
            }
        }
    }
}

int main(){
  
  int n,m;
  cin>>n>>m;
  int imos[n+1] = {};
  int l[m], r[m];
  long long c[m];
  REP(i,m){
    cin>>l[i]>>r[i]>>c[i];
    l[i]--;r[i]--;
    G[l[i]].push_back(edge{r[i], c[i]});
    imos[l[i]]++;
    imos[r[i]+1]--;
  }
  
  REP(i,n){
    if(i==0){
      continue;
    }else{
      imos[i] += imos[i-1];
    }
  }
  for(int i = 1; i<n; i++){
    if(imos[i-1] > 0 && imos[i] > 0){
      G[i].push_back(edge{i-1, 0LL});
    }
  }
  
  dijkstra(0);
  
  if(used[n-1]){
    cout<<dist[n-1]<<endl;
  }else{
    cout<<-1<<endl;
  }
  
      
  return 0;
}
