#include <iostream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#define vv(a, b, c, d) vector<vector<d> >(a, vector<d>(b, c))
#define vvi vector<vector<int> >
#define vvl vector<vector<ll> >
#define vll vector<ll>
#define rep(a, b, c) for(ll c=a;c<b;c++)
#define re(b, c) for(ll c=0;c<b;c++)
typedef long long int ll;
typedef long double ld;
using namespace std;

struct Dijkstra{
  ll INF=1000000000000000009;
  ll MAX_V=1000000;
  ll st = -1;
  struct edge{ll to, cost;};
  typedef pair<ll, ll> p;
  vector<vector<edge>> G;
  vector<ll> pre, d;
  priority_queue<p, vector<p>, greater<p> > que; //class, inner, compair
  Dijkstra(ll s){
    G.resize(s+2);
    pre.resize(s+2, -1);
    d.resize(s+2, INF);
  }
  inline void insert(ll a, ll b, ll c){
    G[a].push_back(edge{b, c});
  }
  void init(){
    for(int i=0;i<d.size();i++) pre[i] = -1, d[i] = INF;
  }
  void dijkstra(int start){
    init();
    st = start;
    d[start]=0;
    que.push(p(0, start));
    while(!que.empty()){
      p p_now=que.top(); que.pop();
      ll v = p_now.second;
      if(d[v]<p_now.first) continue;
      for(int i=0;i<G[v].size();i++){
        edge e = G[v][i];
        if(d[e.to]>d[v]+e.cost){
          d[e.to]=d[v]+e.cost;
          pre[e.to] = v;
          que.push(p(d[e.to], e.to));
        }
      }
    }
  }
  vll get_path(int now){
    vll ret;
    while(now!=-1){
      ret.push_back(now);
      now = pre[now];
    }
    return ret;
  }
};
struct Merge{
  set<vll> lr;
  vll remove(ll a, ll b){
    if(a>b) swap(a, b);
    auto itr = lr.lower_bound(vll{b+1, 0});
    if(itr==lr.begin()) return vll{a, b};
    itr--;
    ll lef = a, ri = b;
    while((*itr)[1]>=a){
      ll now_x = (*itr)[0], now_y = (*itr)[1];
      lef = min(lef, now_x), ri = max(ri, now_y);
      if(itr==lr.begin()){
        lr.erase(itr);
        break;
      }
      itr--;
      lr.erase(vll{now_x, now_y});
    }
    return vll{lef, ri};
  }
  void merge(ll a, ll b){lr.insert(remove(a, b));}
  vll get(ll a){
    auto itr = lr.lower_bound(vll{a+1, 0});
    if(itr==lr.begin()) return vll{-1, -1};
    itr--;
    if((*itr)[1]<a) return vll{-1, -1};
    return *itr;
  }
  bool same(ll a, ll b){
    if(get(a)[0]==-1) return false;
    return get(a)[0]==get(b)[0];
  }
};
//-------------------------------------------------------------------
#include <sstream>
#include <fstream>
ifstream ifs;
void init(string s){ifs.open(s);}
vector<string> split(const string &str, char sep){
    vector<string> v;
    stringstream ss(str);
    string buffer;
    while(getline(ss, buffer, sep)) v.push_back(buffer);
    return v;
}
ll read(){
  string str;
  getline(ifs, str);
  return stoll(str);
}
string read_str(){
  string str;
  getline(ifs, str);
  return str;
}
vector<ll> read_vec(){
  string str;
  getline(ifs, str);
  std::vector<ll> num;
  vector<string> data = split(str, ' ');
  for(int i=0;i<data.size();i++) num.push_back(stoll(data[i]));
  return num;
}
vvl read_mat(ll h){
  string str;
  vvl num = vv(h, 0, 0, ll);
  for(int i=0;i<h;i++){
    getline(ifs, str);
    vector<string> data = split(str, ' ');
    for(int j=0;j<data.size();j++) num[i].push_back(stoll(data[j]));
  }
  return num;
}
//-------------------------------------------------------------------

int main(int argc, char const *argv[]) {
  ll a, b, c, n, m;
  std::cin >> n >> m;
  Dijkstra dk(n);
  Merge mg;
  for(int i=0;i<m;i++){
    std::cin >> a >> b >> c;
    mg.merge(a, b);
    dk.insert(a, b, c);
  }

  for(auto itr = mg.lr.begin(); itr!=mg.lr.end();itr++){
    for(int j=(*itr)[1];j>(*itr)[0];j--){
      dk.insert(j, j-1, 0);
    }
  }
  dk.dijkstra(1);
  std::cout << (dk.d[n]==dk.INF?-1:dk.d[n]) << '\n';
  return 0;
}


Measured memory_bytes: 10232