#include <utility>
#include <cstdint>
#include <type_traits>
#include <string>
#include <iterator>
#include <iostream>
#include <vector>
#include <algorithm>
#include <tuple>
namespace loquat {
namespace bitmanip {
template <typename T>
inline auto clz(T x) noexcept ->
	typename std::enable_if<sizeof(int) < sizeof(T), unsigned int>::type
{
	return __builtin_clzll(x);
}
template <typename T>
inline T clp2(T x) noexcept {
	if(x == 0u){ return 0u; }
	return T(1u) << (sizeof(T) * 8u - clz(x - 1));
}
}
}
namespace loquat {
template <typename Impl>
class lazy_range_query_behavior_wrapper {
public:
	using value_type = typename Impl::value_type;
	using modifier_type = typename Impl::modifier_type;
private:
	Impl m_impl;
	template <typename T>
	static auto split_modifier_helper(
		const T& impl, const modifier_type& m, size_t k)
		-> decltype(impl.split_modifier(m, k))
	{
		return impl.split_modifier(m, k);
	}
	template <typename T>
	static auto modify_helper(
		const T& impl, size_t n, const value_type& v, const modifier_type& m)
		-> decltype(impl.modify(n, v, m))
	{
		return impl.modify(n, v, m);
	}
public:
	lazy_range_query_behavior_wrapper(Impl impl) : m_impl(std::move(impl)) { }
	value_type identity_value() const {
		return m_impl.identity_value();
	}
	modifier_type identity_modifier() const {
		return m_impl.identity_modifier();
	}
	std::pair<modifier_type, modifier_type>
	split_modifier(const modifier_type& m, size_t k) const {
		return split_modifier_helper(m_impl, m, k);
	}
	modifier_type merge_modifier(
		const modifier_type& a, const modifier_type& b) const
	{
		return m_impl.merge_modifier(a, b);
	}
	value_type merge_value(
		const value_type& a, const value_type& b) const
	{
		return m_impl.merge_value(a, b);
	}
	value_type modify(size_t n, const value_type& v, const modifier_type& m) const {
		return modify_helper(m_impl, n, v, m);
	}
};
}
namespace loquat {
template <typename Behavior>
class lazy_segment_tree {
public:
	using behavior_type = Behavior;
	using value_type = typename behavior_type::value_type;
	using modifier_type = typename behavior_type::modifier_type;
private:
	size_t m_actual_size;
	std::vector<value_type> m_values;
	std::vector<modifier_type> m_modifiers;
	lazy_range_query_behavior_wrapper<behavior_type> m_behavior;
	void initialize(){
		const int n = m_values.size() / 2;
		for(int i = n - 1; i >= 0; --i){
			m_values[i] = m_behavior.merge_value(
				m_values[i * 2 + 1], m_values[i * 2 + 2]);
		}
	}
	value_type modify(
		size_t a, size_t b, size_t k, size_t l, size_t r,
		const modifier_type& modifier)
	{
		if(r <= a || b <= l){
			return m_behavior.modify(r - l, m_values[k], m_modifiers[k]);
		}else if(a <= l && r <= b){
			m_modifiers[k] =
				m_behavior.merge_modifier(m_modifiers[k], modifier);
			return m_behavior.modify(r - l, m_values[k], m_modifiers[k]);
		}
		const size_t c = l + (r - l) / 2;
		const size_t lk = k * 2 + 1, rk = lk + 1;
		const auto mp = m_behavior.split_modifier(m_modifiers[k], c - l);
		m_modifiers[k] = m_behavior.identity_modifier();
		modify(l, c, lk, l, c, mp.first);
		modify(c, r, rk, c, r, mp.second);
		const auto mq = (a < c)
			? m_behavior.split_modifier(modifier, c - std::max(a, l))
			: std::make_pair(m_behavior.identity_modifier(), modifier);
		const auto vl = modify(a, b, lk, l, c, mq.first);
		const auto vr = modify(a, b, rk, c, r, mq.second);
		m_values[k] = m_behavior.merge_value(vl, vr);
		return m_values[k];
	}
	value_type query(size_t a, size_t b, size_t k, size_t l, size_t r){
		if(r <= a || b <= l){
			return m_behavior.identity_value();
		}else if(a <= l && r <= b){
			return m_behavior.modify(r - l, m_values[k], m_modifiers[k]);
		}
		const size_t c = l + (r - l) / 2;
		const size_t lk = k * 2 + 1, rk = k * 2 + 2;
		const auto mp = m_behavior.split_modifier(m_modifiers[k], c - l);
		m_values[k] = m_behavior.modify(r - l, m_values[k], m_modifiers[k]);
		m_modifiers[k] = m_behavior.identity_modifier();
		modify(l, c, lk, l, c, mp.first);
		modify(c, r, rk, c, r, mp.second);
		const auto vl = query(a, b, lk, l, c);
		const auto vr = query(a, b, rk, c, r);
		return m_behavior.merge_value(vl, vr);
	}
public:
	lazy_segment_tree(
		size_t size,
		const behavior_type& behavior = behavior_type())
		: m_actual_size(size)
		, m_values(bitmanip::clp2(size) * 2 - 1, behavior.identity_value())
		, m_modifiers(m_values.size(), behavior.identity_modifier())
		, m_behavior(behavior)
	{
		initialize();
	}
	void modify(size_t left, size_t right, const modifier_type& modifier){
		const auto clp2_n = (m_values.size() + 1) / 2;
		modify(left, right, 0, 0, clp2_n, modifier);
	}
	value_type query(size_t left, size_t right){
		const auto clp2_n = (m_values.size() + 1) / 2;
		return query(left, right, 0, 0, clp2_n);
	}
};
}
using namespace std;
using ll = long long;
using tiii = tuple<int, int, ll>;
struct lazy_range_query_behavior {
	using value_type    = ll;
	using modifier_type = ll;
	value_type identity_value() const { return std::numeric_limits<ll>::max(); }
	modifier_type identity_modifier() const { return std::numeric_limits<ll>::max(); }
	std::pair<modifier_type, modifier_type>
	split_modifier(const modifier_type& m, size_t) const {
		return std::make_pair(m, m);
	}
	modifier_type merge_modifier(const modifier_type& a, const modifier_type& b) const {
		return std::min(a, b);
	}
	value_type merge_value(const value_type& a, const value_type& b) const {
		return std::min(a, b);
	}
	value_type modify(size_t, const value_type& v, const modifier_type& m) const {
		return std::min(v, m);
	}
};
int main(){
	ios_base::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	vector<tiii> queries(m);
	for(int i = 0; i < m; ++i){
		int l, r, c;
		cin >> l >> r >> c;
		queries[i] = tiii(l - 1, r, c);
	}
	sort(queries.begin(), queries.end());
	loquat::lazy_segment_tree<lazy_range_query_behavior> lst(n);
	lst.modify(0, 1, 0);
	for(const auto& t : queries){
		const int l = get<0>(t);
		const int r = get<1>(t);
		const ll c = get<2>(t);
		const ll v = lst.query(l, r);
		if(v < std::numeric_limits<ll>::max()){
			lst.modify(l, r, v + c);
		}
	}
	ll answer = lst.query(n - 1, n);
	if(answer == std::numeric_limits<ll>::max()){ answer = -1; }
	cout << answer << endl;
	return 0;
}


Measured memory_bytes: 5888