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

#define int long long

#define rep(i,n) for(int i=0;i<n;i++)

using namespace std;

struct Edge{int to,cost;};

struct Node{

    int v,d;

    bool operator<(const Node&right)const{return d<right.d;}

    bool operator>(const Node&right)const{return d>right.d;}

};

int n,m,l,r,c,d[100009];

vector<Edge> e[100009];



signed main(){

    cin>>n>>m;

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

        e[i+1].push_back({i,0});

        d[i+1]=1e18;

    }

    rep(i,m){

        cin>>l>>r>>c;

        e[l].push_back({r,c});

    }

    priority_queue<Node,vector<Node>,greater<Node>> que;

    que.push({1,0});

    while(!que.empty()){

        Node V=que.top();

        que.pop();

        if(d[V.v]<V.d)continue;

        rep(i,e[V.v].size()){

            if(d[e[V.v][i].to]>V.d+e[V.v][i].cost){

                d[e[V.v][i].to]=V.d+e[V.v][i].cost;

                que.push({e[V.v][i].to,d[e[V.v][i].to]});

            }

        }

    }

    cout<<(d[n]<1e18?d[n]:-1)<<endl;

}

// Faster C++ solution for the same problem (measured speedup: 3.4839222799230387x):
#include <bits/stdc++.h>

#define FOR(i,a,n) for(ll i=(ll)a;i<(ll)n;i++)

#define rep(i,n) FOR(i,0,n)

using namespace std;

typedef long long ll;



const ll mod=1e9+7;



template<class T>bool chmax(T &a,const T &b){

    if(a>b)return false;

    a=b;

    return true;

}

template<class T>bool chmin(T &a,const T &b){

    if(a<b)return false;

    a=b;

    return true;

}



/*-------------------------------------------*/



template<typename T,typename E>

struct SegmentTree{

private:

    typedef function<T(T,T)> F;

    typedef function<T(T,E)> G;

    int n;

    T identity;

    F f;

    G g;

    vector<T> dat;

    void init(int n_){

        n=1;

        while(n<n_)n*=2;

        dat.assign(2*n-1,identity);

    }

    void build(int n_,vector<T> v){

        for(int i=0;i<n_;i++) dat[i+n-1]=v[i];

        for(int i=n-2;i>=0;i--) dat[i]=f(dat[i*2+1],dat[i*2+2]);

    }



public:

    SegmentTree(int n_,F f,G g,T id,vector<T>v=vector<T>()):identity(id),f(f),g(g){

        init(n_);

        if(n_==(int)v.size()) build(n_,v);

    }

    void update(int k,E a){

        k+=n-1;

        dat[k]=g(dat[k],a);

        while(k>0){

            k=(k-1)/2;

            dat[k]=f(dat[k*2+1],dat[k*2+2]);

        }

    }

    T query(int a,int b){

        T vl=identity,vr=identity;

        for(int l=a+n,r=b+n;l<r;l>>=1,r>>=1){

            if(l&1) vl=f(vl,dat[(l++)-1]);

            if(r&1) vr=f(dat[(--r)-1],vr);

        }

        return f(vl,vr);

    }

};



struct s{

    int l,r;

    ll c;

    bool operator<(const s&R)const{return l!=R.l?l<R.l:r<R.r;}

};



int main(){

    int n,m;

    cin>>n>>m;

    vector
v(m);

    rep(i,m){

        int l,r;

        ll c;

        cin>>l>>r>>c;

        v[i]={l-1,r-1,c};

    }

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

    SegmentTree<ll,ll> dp(

        n,

        [](ll a,ll b){return min(a,b);},

        [](ll a,ll b){return min(a,b);},

        1e18

    );

    dp.update(0,0);

    rep(i,m){

        dp.update(v[i].r,dp.query(v[i].l,v[i].r)+v[i].c);

    }

    cout<<(dp.query(n-1,n)<1e18?dp.query(n-1,n):-1)<<endl;

}