// Slower C++ solution:
#include<bits/stdc++.h>

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

using namespace std;

const int N=1e5+5;

typedef long long ll;

const ll inf=(ll)1e18;

ll tr[N<<2];

void change(int p,ll v,int l,int r,int rt){

    if(l==r){

        tr[rt]=min(tr[rt],v);

        return ;

    }

    int m=l+r>>1;

    if(p<=m) change(p,v,lson);

    if(p>m) change(p,v,rson);

    tr[rt]=min(tr[rt<<1],tr[rt<<1|1]);

}

ll query(int L,int R,int l,int r,int rt){

    if(L<=l && r<=R) return tr[rt];

    ll ret=inf;

    int m=l+r>>1;

    if(L<=m) ret=min(ret,query(L,R,lson));

    if(R>m) ret=min(ret,query(L,R,rson));

    return ret;

}

struct node{

    int l,r;

    ll c;

    friend bool operator < (const node &a,const node &b){

        return a.l==b.l?a.c<b.c:a.l<b.l;

    }

};

vector<node> ve;

int main(){

    int n,m;

    scanf("%d %d",&n,&m);

    int l,r;ll c;

    for(int i=1;i<=m;++i){

        scanf("%d %d %lld",&l,&r,&c);

        ve.push_back(node{l,r,c});

    }

    sort(ve.begin(),ve.end());

    fill(tr,tr+(N<<2),inf);

    change(1,0,1,n,1);

    //cout<<"Q: "<<query(1,n,1,n,1)<<"\n";

    for(node p:ve){

        //cout<<p.l<<" "<<p.r<<" "<<p.c<<"\n";

        ll c=p.c+query(p.l,n,1,n,1);

        //cout<<c<<"\n";

        change(p.r,c,1,n,1);

        //cout<<"cuc\n";

    }

    ll anx=query(n,n,1,n,1);

    if(anx==inf) puts("-1");

    else printf("%lld\n",anx);

}


// Faster C++ solution for the same problem (measured speedup: 2.072276660237903x):
#include<iostream>

#include<cstring>

#include<queue>

#include<map>

#include<set>

#include<stack>

#include<cmath>

#include<cstdio>

#include<iomanip>

#include<sstream>

#include<algorithm>

 

using namespace std;

#define read(x) scanf("%d",&x)

#define Read(x,y) scanf("%d%d",&x,&y)

#define sRead(x,y,z)  scanf("%d%d%d",&x,&y,&z)

#define gc(x)  scanf(" %c",&x);

#define  INF (ll)1e14//无穷设置的大着点

#define mmt(x,y)  memset(x,y,sizeof x)

#define write(x) printf("%d\n",x)

const int N = 11000;

const int M=  2e5+5;

using namespace std;

typedef long long ll;

struct Edge

{

    int next;

    int to;

    ll dis;

}edge[M*2];

int head[M],tot;

ll d[M];bool vis[M];

inline void add(int from,int to,ll dis){

    edge[++tot].next = head[from];

    edge[tot].to = to;

    edge[tot].dis = dis;

    head[from] = tot;

}

struct node

{

    ll val;int id;

    node(){}

    node(int a,ll b):id(a),val(b){}

    bool operator <(node A)const{

        return val > A.val;

    }

};

void dij(int u)

{

    mmt(vis,0);

    d[u] = 0;

    priority_queue<node> Q;

    Q.push({u,0});

    node tmp;

    while(Q.size()){

        tmp = Q.top();

        Q.pop();

        int x = tmp.id;

        if(vis[x]) continue;

        for(int i =  head[x];~i;i = edge[i].next){

            int y = edge[i].to;

            ll dis = edge[i].dis;

            if(d[y] > d[x] +dis){

                d[y] = d[x] + dis;

                Q.push({y,d[y]});

            }

        }

    }

}

inline void init(int n)

{

    mmt(head,-1);

    tot = 0;

    for(int i = 1;i <= n;++i) d[i] = INF;

}

int main()

{

    ios::sync_with_stdio(false);

    cin.tie(0);

    int n,m;

    cin>>n>>m;

    init(n);

    int u,v;ll dis;

    for(int i = 1;i <= n;++i){//加反向边

        add(i,i - 1,0);

    }

    for(int i = 1;i <= m;++i){//只把端点 加进去

        cin>>u >> v>>dis;

        add(u,v,dis);

    }

    dij(1);

    if(d[n] == INF) cout<<-1<<endl;

    else cout<<d[n]<<endl;

}