#include<iostream>
#include<vector>
#include<algorithm>
#include<functional>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<unordered_map>
#include<climits>
#include<cstdlib>
#include<cmath>
#include<string>
#include<iomanip>
#include<bitset>
#include<list>

using namespace std;

#define ll long long int

ll const MOD = 1000000007;
ll const INF = (long long int)1 << 61;

ll mypow(ll x,ll n,ll mod = MOD){
    ll ret = 1;
    while(n > 0){
        if(n&1){
            ret = (ret*x)%mod;
        }
        x = (x*x)%mod;
        n >>= 1;
    }
    return ret;
}

ll mygcd(ll a,ll b){
    if(b == 0)return a;
    return mygcd(b,a%b);
}

ll twoPow(ll shiftNum){
    return (1LL << (shiftNum - 1));
}

template<typename dataType>
class SegmentTree{
    int dataSize;
    dataType initialVal;
    std::vector<dataType> tree;
    std::function<dataType(dataType,dataType)> addFunc;
    std::function<dataType(dataType,dataType)> extFunc;

    void internalUpdate(int pointedIndex){
        while(pointedIndex > 1){
            pointedIndex >>= 1;
            tree[pointedIndex] = extFunc(tree[pointedIndex*2],tree[pointedIndex*2+1]);
        }
    }

public:

    SegmentTree(int N, dataType init,
                function<dataType(dataType,dataType)> f1 = [](dataType a,dataType b)->dataType{return a+b;},
                function<dataType(dataType,dataType)> f2 = [](dataType a,dataType b)->dataType{return a+b;})
                :initialVal(init),addFunc(f1),extFunc(f2){
                    dataSize = 1;
                    while(dataSize < N){
                        dataSize *= 2;
                    }
                    tree = std::vector<dataType>(dataSize*2,initialVal);
                }

    void initialize(vector<dataType> data){
        for(int i = dataSize; i < dataSize*2 && i - dataSize < data.size(); i++){
            tree[i] = data[i - dataSize];
        }
        for(int i = dataSize - 1; i > 0; i--){
            tree[i] = extFunc(tree[i*2],tree[i*2+1]);
        }
    }

    bool updateQuery(int index,dataType newVal){
        if(index < 1 || index > dataSize){
            return false;
        }
        int pointedIndex = dataSize + index - 1;
        tree[pointedIndex] = newVal;
        internalUpdate(pointedIndex);
        return true;
    }

    bool addQuery(int index,dataType newVal){
        if(index < 1 || index > dataSize){
            return false;
        }
        int pointedIndex = dataSize + index - 1;
        tree[pointedIndex] = addFunc(tree[pointedIndex],newVal);
        internalUpdate(pointedIndex);
        return true;
    }

    dataType getQuery(int leftIndex , int rightIndex){
        if(leftIndex > rightIndex || leftIndex < 1 || rightIndex > dataSize){
            return initialVal;
        }else if(leftIndex == rightIndex){
            return tree[dataSize + leftIndex - 1];
        }

        int leftPointedIndex = dataSize + leftIndex - 1;
        int rightPointedIndex = dataSize + rightIndex - 1;

        dataType leftVal = tree[leftPointedIndex];
        dataType rightVal = tree[rightPointedIndex];
        
        while(true){
            bool wasLeftEven = (leftPointedIndex % 2 == 0);
            bool wasRightEven = (rightPointedIndex % 2 == 0);

            leftPointedIndex >>= 1;
            rightPointedIndex >>= 1;

            if(leftPointedIndex == rightPointedIndex){
                return extFunc(leftVal,rightVal);
            }

            if(wasLeftEven){
                leftVal = extFunc(leftVal,tree[leftPointedIndex*2 + 1]);
            }

            if(!wasRightEven){
                rightVal = extFunc(rightVal,tree[rightPointedIndex*2]);
            }
        }

        return initialVal;
    }
};

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
 
    ll n,m;
    cin >> n >> m;

    vector<ll> l(m),r(m),c(m);
    for(int i = 0; i < m; i++){
        cin >> l[i] >> r[i] >> c[i];
    }

    vector<tuple<ll,ll,ll>> edge;
    for(int i = 0; i < m; i++){
        edge.push_back(make_tuple(l[i],c[i],r[i]));
    }

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

    auto f1 = [](pair<ll,ll> a,pair<ll,ll> b)->pair<ll,ll>{
        return {a.first + b.first,a.second};
    };

    auto f2 = [](pair<ll,ll> a,pair<ll,ll> b)->pair<ll,ll>{
        if(a.first > b.first){
            return b;
        }else{
            return a;
        }
    };

    SegmentTree<pair<ll,ll>> st(n,{INF,-1},f1,f2);

    st.updateQuery(1,{0,1});
    for(int i = 2; i <= n; i++){
        st.updateQuery(i,{INF,i});
    }

    for(int i = 0; i < edge.size(); i++){
        ll pos = st.getQuery(get<0>(edge[i]),get<2>(edge[i])).first + get<1>(edge[i]);
        ll ng = get<0>(edge[i]) - 1;
        ll ok = get<2>(edge[i]) + 1;
        while(abs(ok - ng) > 1){
            ll middle = (ok + ng)/2;
            if(st.getQuery(middle,middle).first > pos){
                ok = middle;
            }else{
                ng = middle;
            }
        }
        for(int j = ok; j <= get<2>(edge[i]); j++){
            st.updateQuery(j,{pos,j});
        }
    }

    if(st.getQuery(n,n).first >= INF){
        cout << -1 << endl;
        return 0;
    }

    cout << st.getQuery(n,n).first << endl;

    return 0;
}

Measured memory_bytes: 9712