// Original C++ solution (slower):
#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;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>



#define SORT(v) sort(v.begin(),v.end())

#define si(n) scanf("%d",&n)

#define sii(n,m) scanf("%d %d",&n,&m)

#define sl(n) scanf("%lld",&n)

#define sll(n,m) scanf("%lld %lld",&n,&m)

#define ss(cad) scanf("%s",cad)

#define PB push_back

#define fst first

#define scn second

#define DBG(x) cerr << #x << " = " << (x) << endl; 

#define M 1000000007

#define N_MAX 100010



using namespace std;



typedef long long ll;

typedef vector<int> vi;

typedef vector<bool> vb;

typedef vector<ll> vl;

typedef pair<int,int> pi;

typedef vector<pi> vp;



int main()

{

	int n, m;

	sii(n, m);

	vector<pair<pi, int> > vec;

	vl in(m);

	vl dist(n, -1);

	vl curr(m, -1);



	vp puntos;

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

	{

		int val;

		si(val);

		val--;

		puntos.push_back({val, i});

		si(val);

		val--;

		puntos.push_back({val, i});

		sl(in[i]);

	}



	SORT(puntos);

	multiset<ll> lista;

	dist[0] = 0;

	int pos = 0;

	while(pos < puntos.size() && puntos[pos].fst == 0)

	{

		lista.insert(in[puntos[pos].scn]);

		curr[puntos[pos].scn] = in[puntos[pos].scn];

		pos++;

	}



	bool sw = 1;

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

	{

		if(!lista.empty())

			dist[i] = *lista.begin();

		else

		{

			sw = 0;

			break;

		}



		while(pos < puntos.size() && puntos[pos].fst == i)

		{

			if(curr[puntos[pos].scn] != -1)

			{

				lista.erase(lista.find(curr[puntos[pos].scn]));

				curr[puntos[pos].scn] = -1;

			}

			else

			{

				lista.insert(dist[i] + in[puntos[pos].scn]);

				curr[puntos[pos].scn] = dist[i] + in[puntos[pos].scn];

			}

			pos++;

		}

	}



	if(sw)

		printf("%lld\n", dist[n-1]);

	else

		printf("-1\n");

    

    return 0;

}


// Fastest known solution for this problem: