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

using namespace std;



typedef long long ll;

ll tr[4100000];

struct rp {

    int x, y;

    ll z;

} a[110000];

vector<int> v[110000];

int n, m, all;



void getnew(int root) {

    root /= 2;

    while (root) {

        tr[root] = min(tr[root * 2], tr[root * 2 + 1]);

        root /= 2;

    }

}



ll getmin(int l, int r) {

    ll ans = 1e15;

    while (r - l > 1) {

        if (l % 2 == 0)

            ans = min(ans, tr[l + 1]);

        if (r % 2 == 1)

            ans = min(ans, tr[r - 1]);

        l >>= 1, r >>= 1;

    }

    return ans;

}



int main() {

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

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

        scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);

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

        v[a[i].y].push_back(i);

    }

    all = 1;

    while (all <= n)

        all <<= 1;

    all--;

    for (int i = 1; i <= all + all + 1; i++)

        tr[i] = 1e15;

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

        if (a[i].x == 1) {

            tr[all + a[i].y] = a[i].z;

            getnew(all + a[i].y);

        }

    }

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

        for (auto j:v[i]) {

            ll now = getmin(all + a[j].x - 1, all +a[j].y + 1) + a[j].z;

            if (now < tr[all + a[j].y]) {

                tr[all + a[j].y] = now;

                getnew(all + a[j].y);

            }

        }

    }

  //  printf("%lld..\n", tr[all + n]);

    if (tr[all + n] < 1e15) {

        printf("%lld\n", tr[all + n]);

    } else puts("-1");

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.853027474723242x):
#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;

}