//
//  main.cpp
//
 
#include <algorithm>
#include <array>
#include <assert.h>
#include <functional>
#include <iostream>
#include <iomanip>
#include <limits>
#include <map>
#include <math.h>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
 
using namespace std;
 
using ll = long long;
using ull = unsigned long long;
 
template<typename T>
vector<T> make_vec_nd(T init, size_t size) {
	return vector<T>(size, init);
}
template<typename T, typename... Args>
auto make_vec_nd(T init, size_t size, Args... rest) {
	auto inner = make_vec_nd(init, rest...);
	return vector<decltype(inner)>(size, inner);
}

#define rep(i,a,b) for(ll i=a;i<b;i++)
#define rrep(i,a,b) for(ll i=a-1;i>=b;i--)

template<typename Monoid>
struct SegmentTree {
	using Op = function<Monoid(const Monoid& lhs, const Monoid& rhs)>;
	size_t width;
	vector<Monoid> node;
	Op op;
	Monoid unit;
 
	SegmentTree(const vector<Monoid>& elems, Op op, Monoid unit)
	: op(op)
	, unit(unit) {
		width = 1;
		while (width < elems.size()) {
			width *= 2;
		}
		node.resize(2 * width - 1, unit);
		for (size_t i = 0; i < elems.size(); i++) {
			node[i + width - 1] = elems[i];
		}
		for (size_t i = width - 2; i != numeric_limits<size_t>::max(); i--) {
			node[i] = op(node[2 * i + 1], node[2 * i + 2]);
		}
	}
	void update(size_t idx, Monoid elem) {
		idx += width - 1;
		node[idx] = elem;
		while (idx >= 1) {
			idx = (idx - 1) / 2;
			node[idx] = op(node[2 * idx + 1], node[2 * idx + 2]);
		}
	}
	Monoid query(size_t a, size_t b, size_t root) const {
		assert(0 <= a && b <= width);
		size_t left = root, right = root;
		while (left < width - 1) {
			left = 2 * left + 1;
		}
		left -= (width - 1);
		while (right < width - 1) {
			right = 2 * right + 2;
		}
		right -= (width - 1);
		right++;
		if (right <= a || b <= left) {
			return unit;
		}
		if (a <= left && right <= b) {
			return node[root];
		}
		Monoid ans_l = query(a, b, 2 * root + 1);
		Monoid ans_r = query(a, b, 2 * root + 2);
		return op(ans_l, ans_r);
	}
};

int main() {
	ll N, M;
	cin >> N >> M;
	struct Range {
		ll L;
		ll R;
		ll C;
	};
	vector<Range> ranges;
	rep(i,0,M) {
		ll l, r, c;
		cin >> l >> r >> c;
		l--;
		r--;
		ranges.push_back(Range{l, r, c});
	}
	sort(ranges.begin(), ranges.end(), 
		 [](Range lhs, Range rhs){ return lhs.R < rhs.R; });
	vector<ll> dp_init(N, numeric_limits<int>::max());
	SegmentTree<ll> dp(dp_init, [](ll lhs, ll rhs){ return min(lhs, rhs); },
						numeric_limits<int>::max());
	dp.update(0, 0);
	rep(i,0,M) {
		Range range = ranges[i];
		ll now = dp.query(range.R, range.R+1, 0);
		ll v = dp.query(range.L, range.R, 0) + range.C;
		dp.update(range.R, min(now, v));
	}
	ll ans = dp.query(N-1, N, 0);
	if (ans >= numeric_limits<int>::max()) {
		cout << -1 << endl;
	} else {
		cout << ans << endl;
	}
}
