/* ＵＴＦ－８ */
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <array>
#include <queue>
#include <stack>
#include <algorithm>
#include <tuple>
#include <numeric>
#include <type_traits>
#include <limits>

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define USE_COLORED 1

#ifdef USE_COLORED
static const char stdout_pre[]  = "\033[1m"; // bold black
static const char stderr_pre[]  = "\033[31;1m"; // bold red
static const char stdxxx_post[] = "\033[m";

// 当然ながら GCC(g++)/libstdc++ 依存
#include <ext/stdio_filebuf.h>
using stdio_filebuf = __gnu_cxx::stdio_filebuf<char>;
class colored_stdio_filebuf : public stdio_filebuf {
private:
	const char* const pre_;
	const char* const post_;

public:
	colored_stdio_filebuf(FILE* fp, const char* pre, const char* post) : stdio_filebuf(fp, std::ios_base::out), pre_(pre), post_(post)
	{
	}

protected:
	std::streamsize xsputn(const char* s, std::streamsize count) override
	{
		stdio_filebuf::xsputn(pre_, strlen(pre_));
		auto ret = stdio_filebuf::xsputn(s, count);
		stdio_filebuf::xsputn(post_, strlen(post_));
		return ret;
	}
};
#endif

struct LRC {
	int L, R;
	long C;
};

template<typename W, typename V>
struct dijkstra_result {
	std::vector<W> distance; // 距離
	std::vector<V> prev; // 「前」の頂点
};

/**
 * ダイクストラ法で、ある頂点から到達可能な頂点までの距離と最短経路を求める
 * 
 * @tparam G グラフを表す型。
 *           グラフ g で頂点 u から v への重み w の辺があることを g[u][v] = w で表す。無向グラフなら g[u][v] = g[v][u] にしておく
 *           G は map<V, map<V, W>> や vector<vector<pair<V, W>>> などが可能
 * @tparam V 頂点番号の型。普通は int にすると思う
 * @tparam W 重みの型。 G から求まるので指定しなくてよい
 */
template<typename G, typename V, typename W = typename std::remove_reference<decltype(std::declval<G>()[0][0])>::type>
dijkstra_result<W, V> dijkstra(/*const*/ G& graph, V start, V num)
{
	using PQT = std::pair<W, V>;

	std::vector<W> distance;
	std::vector<V> prev;
	std::deque<bool> done; // 既に確定している頂点かどうか（覚えておかなくても計算できるが無駄がある）
	std::priority_queue<PQT, std::vector<PQT>, std::greater<PQT>> q;

	distance.resize(num);
	prev.resize(num);
	done.resize(num);

	for (V i = 0; i < num; ++i) {
		distance[i] = std::numeric_limits<W>::max();
	}
	distance[start] = 0;
	q.push({0, start});

	while (!q.empty()) {
		const auto& du = q.top();
		const auto dist = du.first;
		const auto u = du.second;
		q.pop();
		done[u] = true;
		const auto& edges = graph[u];
		for (const auto& vw : edges) {
			const auto v = vw.first;
			const auto w = vw.second;
			if (!done[v]) {
				long updated = dist + w;
				if (distance[v] > updated) {
					distance[v] = updated;
					prev[v] = u;
					q.push({updated, v});
				}
			}
		}
	}

	return {distance, prev};
}

int main()
{
#ifdef USE_COLORED
	if (getenv("DEBUG")) {
		std::cout.rdbuf(new colored_stdio_filebuf(stdout, stdout_pre, stdxxx_post));
		std::cerr.rdbuf(new colored_stdio_filebuf(stderr, stderr_pre, stdxxx_post));
	} else
#endif
	{
		int fd = open("/dev/null", O_WRONLY);
		dup2(fd, 2);
		close(fd);
	}

	int N, M;
	std::vector<LRC> mods;
	std::cin >> N >> M;
	mods.resize(M);
	for (auto& m : mods) {
		std::cin >> m.L >> m.R >> m.C;
		--m.L;
		m.R;
	}

	std::set<int> divs;
	for (const auto& m : mods) {
		divs.insert(m.L);
		divs.insert(m.R);
	}

	std::vector<int> groups;
	{
		groups.resize(N);
		int g = 0;
		auto it = divs.begin();
		++it;
		for (int i = 1; i < N; ++i) {
			if (*it == i) {
				++g;
				++it;
			}
			groups[i] = g;
		}
	}

	std::map<int, std::unordered_map<int, long>> g;
	for (int k = 0; k < mods.size(); ++k) {
		const auto& m = mods[k];
std::cerr << "add edge " << k << ": " << groups[m.L] << " " << groups[m.R] << "\n";
		for (int i = groups[m.L]; i <= groups[m.R-1]; ++i) {
			g[i][N+k*2] = 0;
			g[N+k*2+1][i] = 0;
		}
		g[N+k*2][N+k*2+1] = m.C;
	}

std::cerr << "groups:\n";
for (int i = 0; i < N; ++i) {
	std::cerr << groups[i] << " ";
}
std::cerr << "\nedges:\n";
for (auto& gg : g) {
	std::cerr << gg.first << " -> ";
	for (auto& ggg : gg.second) {
		std::cerr << "(" << ggg.first << "," << ggg.second << ") ";
	}
	std::cerr << "\n";
}

	auto r = dijkstra(g, 0, N+M*2);
	long dist = r.distance[groups[N-1]];
	if (dist == std::numeric_limits<long>::max())
		dist = -1;
	std::cout << dist << "\n";
}
