#include <iostream>
#include <iomanip>
#include <random>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <numeric>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <sstream>
#include <bitset>
#include <cassert>
#include <fstream>
#include <queue>

#define len(X) ((int)(X).size())

#ifdef __LOCAL
	#define DBG(X) cout << #X << "=" << (X) << '\n';
	#define SAY(X) cout << (X) << '\n';
#else
	#define DBG(X)
	#define SAY(X)
#endif
 
using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld  = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

const int INT_INF = (int)(2e9);
const ll  LL_INF  = (ll)(2e18);

const int NIL = -1;
static mt19937 _g(time(nullptr));

inline ll randint(ll a, ll b) { ll w = (_g() << 31LL) ^ _g(); return a + w % (b - a + 1); }
inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };
template<typename T> inline T sign(T x) { return T(x > 0) - T(x < 0); }
template<typename T, typename S> inline ostream& operator<<(ostream& os, const pair<T, S> p) { cout << "[" << p.first << ";" << p.second << "]"; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const vector<T>& v) { for(auto el: v) cout << el << " "; return os; }
template<typename T> inline T fetch() { T ret; cin >> ret; return ret; }
template<typename T> inline vector<T> fetch_vec(int sz) { vector<T> ret(sz); for(auto& elem: ret) cin >> elem; return ret; }

const int MAXN = (int)1e5 + 777;
const int MAXV = (int)2e6 + 888;

vector<pii> g[MAXV];
int V = 0;
int n, m;
int up[4 * MAXN], down[4 * MAXN];

int add_vertex() {
	return V++;
}

void add_edge(int v, int u, int c) {
#ifdef __LOCAL
	cout << "@@edge: " << v << ' ' << u << ' ' << c << '\n';
#endif
	g[v].emplace_back(u, c);
}

void build(int v, int tl, int tr) {
	up[v] = add_vertex();
	down[v] = add_vertex();

	if(tl == tr) {
		add_edge(up[v], down[v], 0);
		add_edge(down[v], up[v], 0);
	} else {
		int tm = (tl + tr) / 2;
		build(2 * v + 1, tl, tm);
		build(2 * v + 2, tm + 1, tr);

		add_edge(down[v], down[2 * v + 1], 0);
		add_edge(down[v], down[2 * v + 2], 0);

		add_edge(up[2 * v + 1], up[v], 0);
		add_edge(up[2 * v + 2], up[v], 0);
	}
}

void add(int v, int tl, int tr, int l, int r, int node, int cost) {
	DBG(v); DBG(l); DBG(r);

	if(tl == l && tr == r) {
		add_edge(up[v], node, cost);
		add_edge(node, down[v], 0);
	} else {
		int tm = (tl + tr) / 2;

		if(r <= tm) {
			add(2 * v + 1, tl, tm, l, r, node, cost);
		} else if(l >= tm + 1) {
			add(2 * v + 2, tm + 1, tr, l, r, node, cost);
		} else {
			add(2 * v + 1, tl, tm, l, tm, node, cost);
			add(2 * v + 2, tm + 1, tr, tm + 1, r, node, cost);
		}
	}
}

int get_leaf(int v, int tl, int tr, int pos) {
	if(tl == tr) {
		return v;
	} else {
		int tm = (tl + tr) / 2;

		if(pos <= tm) {
			return get_leaf(2 * v + 1, tl, tm, pos);
		} else {
			return get_leaf(2 * v + 2, tm + 1, tr, pos);
		}
	}
}

ll dist[MAXV];
set<pll> setik;

void solve() {
	cin >> n >> m;
	build(0, 0, n - 1);

	for(int i = 0; i < m; ++i) {
		int L = fetch<int>() - 1;
		int R = fetch<int>() - 1;
		int c = fetch<int>();

		int node = add_vertex();

		add(0, 0, n - 1, L, R, node, c);
	}

	const int src = up[get_leaf(0, 0, n - 1, 0)];
	const int dst = up[get_leaf(0, 0, n - 1, n - 1)];

	for(int i = 0; i < V; ++i) {
		dist[i] = LL_INF;
	}

	dist[src] = 0;

	for(int i = 0; i < V; ++i) {
		setik.emplace(dist[i], i);
	}

	while(!setik.empty()) {
		auto fst = setik.begin();
		int v = fst->second;
		setik.erase(fst);

		for(auto& ed: g[v]) {
			int u = ed.first;

			if(dist[u] > dist[v] + ed.second) {
				setik.erase(make_pair(dist[u], u));
				dist[u] = dist[v] + ed.second;
				setik.emplace(dist[u], u);
			}
		}
	}

#ifdef __LOCAL
	for(int i = 0; i < V; ++i) {
		cout << '@' << i << ' ' << dist[i] << '\n';
	}
#endif

	cout << (dist[dst] == LL_INF ? -1 : dist[dst]) << '\n';
}

int main() {
	fast_io();
	solve();

	return 0;
}


Measured memory_bytes: 131440