#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#include <functional>
#include <iomanip>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <stack>
#include <queue>
#include <deque>
#include <bitset>
#include <array>
#include <list>
#include <forward_list>
#include <complex>
#include <numeric>
#include <regex>
//#include <optional>
#include <boost/optional.hpp>
//#include <boost/multiprecision/cpp_int.hpp>
//#include <boost/range/irange.hpp>

using namespace std;

//#define int Int
#define let auto const&
#define var decltype(auto)
#define ref auto&&

using Int = std::int_fast64_t;
using Uint = std::uint_fast64_t;

using ll = long long;
using ld = long double;

template<class T=int> using vec = std::vector<T>;
template<class T=int> using mat = std::vector<std::vector<T>>;
template<class T=int> using dic = std::map<std::string, T>;
template<class T=int> using dict = std::unordered_map<std::string, T>;
template<class T=int> using pqg = std::priority_queue<T, std::vector<T>, std::greater<>>;
template<class T=int, class F=std::less<>> using pq = std::priority_queue<T, std::vector<T>, F>;

using vi = std::vector<int>;
using mi = std::vector<std::vector<int>>;
using vl = std::vector<ll>;
using ml = std::vector<std::vector<ll>>;
using pii = std::pair<int, int>;
using vpi = std::vector<pii>;
using pll = std::pair<ll, ll>;
using vpl = std::vector<pll>;
using vb = std::vector<bool>;

template<class T=int> using opt = boost::optional<T>;
using boost::optional;
const auto none = boost::none;
//const auto none = std::nullopt;
//using cint = boost::multiprecision::cpp_int;
//using boost::irange;

constexpr int IINF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int INF = (int)LINF;

constexpr long long MOD = 1e9+7;

#define overload4(a,b,c,d,name,...) name
#define rep1(n) for(int i=0,end_i=(n);i<end_i;++i)
#define rep2(i,n) for(int i=0,end_##i=(n);i<end_##i;++i)
#define rep3(i,a,b) for(int i=(a),end_##i=(b);i<end_##i;++i)
#define rep4(i,a,b,c) for(int i=(a),end_##i;i<end_##i;i+=(c))
#define rep(...) overload4(__VA_ARGS__,rep4,rep3,rep2,rep1)(__VA_ARGS__)
#define rrep1(n) for(int i=(n)-1;i>=0;--i)
#define rrep2(i,n) for(int i=(n)-1;i>=0;--i)
#define rrep3(i,a,b) for(int i=(b)-1,begin_##i=(a);i>=begin_##i;--i)
#define rrep4(i,a,b,c) for(int i=((b)-(a)-1)/(c)*(c)+(a),begin_##i=(a);i>=begin_##i;i-=c)
#define rrep(...) overload4(__VA_ARGS__,rrep4,rrep3,rrep2,rrep1)(__VA_ARGS__)

#define elif else if
#define nif(a) if(!(a))

#define all(a) std::begin(a), std::end(a)
#define call(a) std::cbegin(a), std::cend(a)
#define rall(a) std::rbegin(a), std::rend(a)

#define eb emplace_back
#define pb push_back

#define mp make_pair
#define fi first
#define se second

template<class C> constexpr C& rev(C& a) { std::reverse(std::begin(a), std::end(a)); return a; }
template<class C> constexpr C rev(C&& a) { return std::forward<C>(rev(a)); }
template<class C> constexpr C& sort(C& a) { std::sort(std::begin(a), std::end(a)); return a; }
template<class C> constexpr C sort(C&& a) { return std::forward<C>(sort(a)); }
template<class C> constexpr bool np(C& a) { return std::next_permutation(std::begin(a), std::end(a)); }
template<class C> constexpr bool pp(C& a) { return std::prev_permutation(std::begin(a), std::end(a)); }
template<class C> constexpr auto& min(C const& a) { return *std::min_element(std::begin(a), std::end(a)); }
template<class C> constexpr auto& max(C const& a) { return *std::max_element(std::begin(a), std::end(a)); }
template<class C> constexpr auto total(C const& c) { return std::accumulate(std::next(std::begin(c)), std::end(c), *std::begin(c)); }
template<class C, class F> constexpr auto foldl(C const& c, F const& f) { return std::accumulate(std::next(std::begin(c)), std::end(c), *std::begin(c), f); }

template<class T> constexpr auto RLE(std::vector<T> const& v) { // run length encoding
  std::vector<std::pair<T, std::size_t>> w{}; auto t=std::begin(v); std::size_t cnt=0;
  for(auto i=std::begin(v); i!=std::end(v); ++i) { if(*t == *i) ++cnt; else w.emplace_back(*t, cnt), t=i, cnt=1; }
  if(cnt > 0) w.emplace_back(*t, cnt); return w;
}

template<class T> auto cum_sum(std::vector<T> const& v) {
  std::vector<T> a(v.size()+1);
  for(std::size_t i=0;i<a.size();++i) a[i+1] = a[i] + v[i];
  return a;
}

template<class T> constexpr T gcd2(T a, T b) { while(b) { T t=b; b=a%b; a=t; } return a; }
template<class T> constexpr T lcm2(T a, T b) { return a/gcd2(a,b)*b; }
template<class T> constexpr T extgcd2(T a, T b, T& x, T& y) { x=1; y=0; while(b) { T t=a/b; T u=b; b=a-t*b; a=u; u=y; y=x-t*y; x=u; } return a; }

template<class T> constexpr bool chmax(T& a, T const& b) { if (a < b) { a = b; return true; } return false; }
template<class T> constexpr bool chmin(T& a, T const& b) { if (b < a) { a = b; return true; } return false; }

template<class T, class U> constexpr T ceil(T const& A, U const& B) { return (A+B-1) / B; } // ceil(A/B)

#define mv(T,...) make_v<T>(__VA_ARGS__)
template<class T> constexpr auto make_v() { return std::vector<T>(); } template<class T> constexpr auto make_v(std::size_t a) { return std::vector<T>(a); }
template<class T, class... Ts> constexpr auto make_v(std::size_t a, Ts... ts) { return std::vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...)); }

template<class T> struct has_itr {
  template<class U> static auto check(U x) -> decltype(std::begin(x), std::end(x), std::true_type()); static std::false_type check(...);
  static bool constexpr value = decltype(check(std::declval<T>()))::value;
};
template<class T, class V, std::enable_if_t<!has_itr<T>::value, std::nullptr_t> = nullptr> constexpr void fill_v(T& t, V const& v) { t = v; }
template<class T, class V, std::enable_if_t< has_itr<T>::value, std::nullptr_t> = nullptr> constexpr void fill_v(T& t, V const& v) { for(auto&& e : t) fill_v(e, v); }

template<class T, class U> std::istream& operator>>(std::istream& is, std::pair<T, U>& p) { is >> p.first >> p.second; return is; }
template<class T, class U> std::ostream& operator<<(std::ostream& os, std::pair<T, U> const& p) { os << '(' << p.first << ',' << p.second << ')'; return os; }
template<class T> std::istream& operator>>(std::istream& is, std::vector<T>& v) { for(auto&& x : v) is >> x; return is; }
template<class T> struct is_string : std::false_type {}; template<> struct is_string<std::string> : std::true_type {};
template<class T, std::enable_if_t<has_itr<T>::value && !is_string<T>::value, std::nullptr_t> = nullptr> std::ostream& operator<<(std::ostream& os, T const& t)
{ for(auto i=std::begin(t);i!=std::end(t);++i) { if(i!=std::begin(t)) os<<' '; os<<*i; } return os; }

template<class T> struct has_front {
  template<class U> static auto check(U x) -> decltype(x.front(), x.pop(), std::true_type()); static std::false_type check(...);
  static bool constexpr value = decltype(check(std::declval<T>()))::value;
};
template<class T> struct has_top {
  template<class U> static auto check(U x) -> decltype(x.top(), x.pop(), std::true_type()); static std::false_type check(...);
  static bool constexpr value = decltype(check(std::declval<T>()))::value;
};
template<class T, std::enable_if_t< has_front<T>::value, std::nullptr_t> = nullptr> constexpr auto pop_front(T& p) { auto q = p.front(); p.pop(); return q; }
template<class T, std::enable_if_t< has_top<T>::value, std::nullptr_t> = nullptr> constexpr auto pop_top(T& p) { auto q = p.top(); p.pop(); return q; }
template <class T=int, class F=std::greater<>> auto make_pq(F const& f=F()) { return std::priority_queue<T, std::vector<T>, F>(f); }

struct SetDigit {
  int n; constexpr SetDigit(int _n) : n(_n) {}
  friend std::ostream& operator<<(std::ostream& os, SetDigit sd) { os << std::fixed << std::setprecision(sd.n); return os; }
};
constexpr auto setd(int n) { return SetDigit(n); };
struct ZeroFill {
  int n; constexpr ZeroFill(int _n) : n(_n) {}
  friend std::ostream& operator<<(std::ostream& os, ZeroFill zf) { os << std::setfill('0') << std::setw(zf.n); return os; }
};
constexpr auto zfl(int n) { return ZeroFill(n); }
struct InitIO {
  InitIO() {
    std::cin.tie(nullptr); std::cout.tie(nullptr); std::cerr.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << setd(15) << std::boolalpha;
    std::cerr << setd(15) << std::boolalpha;
    #ifndef LOCAL
      std::cerr.rdbuf(nullptr);
    #endif
  }
} initio;
#ifdef LOCAL
  #include <boost/type_index.hpp>
  #define trace(...) Trace(" " #__VA_ARGS__ ",", __VA_ARGS__)
  template<class T> inline std::string type_name() { return boost::typeindex::type_id_with_cvr<T>().pretty_name(); }
  template<class T> inline char const* Trace(char const* n, T const& t) {
    auto c = std::strchr(n+1, ','); std::cerr.write(n, c-n) << " = " << t << "; // " << type_name<T>() << "\n"; return c; }
  template<class T, class... Ts> inline char const* Trace(char const* n, T const& t, Ts const&... ts) {
    char const* c = Trace(n, t); return Trace(c+1, ts...); }
#else
  #define trace(...)
#endif

#define in(T,...) In<T>(__VA_ARGS__)
template<class T> inline T& sc(T& x) { std::cin >> x; return x; }
template<class T, class... Ts> inline void sc(T& t, Ts&... ts) { sc(t); sc(ts...); }
template<class T=int> inline T In() { T x; sc(x); return x; }
template<class T, class... Ts> inline auto In(Ts ...ts) { auto v = make_v<T>(ts...); sc(v); return v; }
inline std::string input(bool c=true) { std::string str; if(c) std::cin >> std::ws; std::getline(std::cin, str); return str; }
template<class T> inline signed out(T const& x) { std::cout << x; return 0; }
template<class T, class... Ts> inline signed out(T const& t, Ts const&... ts) { out(t); out(' '); out(ts...); return 0; }
template<class T> inline signed err(T const& x) { std::cerr << x; return 0; }
template<class T, class... Ts> inline signed err(T const& t, Ts const&... ts) { err(t); err(' '); err(ts...); return 0; }
template<class... Ts> inline signed print(Ts const&... ts) { out(ts...); return out('\n'); }
template<class... Ts> inline signed debug(Ts const&... ts) { err(ts...); return err('\n'); }

constexpr auto yes(bool c=true) { return c ? "yes" : "no"; }
constexpr auto Yes(bool c=true) { return c ? "Yes" : "No"; }
constexpr auto YES(bool c=true) { return c ? "YES" : "NO"; }


// adjacency list (weighted graph)
template<class T> struct GraphL {
  using size_t = std::size_t;
  struct E {
    size_t to; T w;
    E(size_t to) : to(to), w() {}
    E(size_t to, T w) : to(to), w(w) {}
  };
  size_t n; std::vector<std::vector<E>> dat;
  GraphL() {}
  GraphL(size_t n) : n(n), dat(n) {}
  void init(size_t n) { this->n = n; dat.assign(n, std::vector<E>()); }
  auto& operator[](size_t i) { return dat[i]; }
  auto& operator[](size_t i) const { return dat[i]; }
  auto begin() { return dat.begin(); }
  auto begin() const { return dat.begin(); }
  auto end() { return dat.end(); }
  auto end() const { return dat.end(); }
  size_t size() const { return n; }
  void de(size_t i, size_t j, T t) { dat[i].push_back(E(j, t)); }
  void e(size_t i, size_t j, T t) { de(i, j, t); de(j, i, t); }
  friend std::ostream& operator<<(std::ostream& os, GraphL const& g) {
    for(size_t i=0;i<g.size();++i) {
      os << i+1 << " -->";
      for(size_t j=0;j<g[i].size();++j)
        os << ' ' << g[i][j].to+1 << '(' << g[i][j].w << ')';
      if(i+1 < g.size()) os << '\n';
    }
    return os;
  }
};

template<class U, class T, class Cp=std::less<>, class Op=std::plus<>>
auto dijkstra(GraphL<T> const& g, std::size_t s, U u, Cp cp=Cp(), Op op=Op()) {
  using pr = std::pair<U, std::size_t>;
  std::vector<optional<U>> r(g.size());
  const auto f = [cp](pr const& p, pr const& q) -> bool { return cp(q.first, p.first); };
  std::priority_queue<pr, std::vector<pr>, decltype(f)> que(f);
  que.emplace(*(r[s]=u), s);
  while(!que.empty()) {
    U w; std::size_t v; std::tie(w, v) = que.top(); que.pop();
    if(r[v] && cp(*r[v], w)) continue;
    for(auto const& e : g[v]) {
      U nw = op(w, e.w);
      if(!r[e.to] || cp(nw, *r[e.to])) que.emplace(*(r[e.to]=nw), e.to);
    }
  }
  return r;
}

constexpr int lim = 1e5+7;



signed main() {

  int N = in(), M = in();
  GraphL<ll> g(N);
  rep(i, M) {
    int L = in(), R = in();
    ll C = in(ll);
    g.de(--L, --R, C);
    rep(j, L, R) g.de(R, j, 0);
  }
  let ans = dijkstra<ll>(g, 0, 0);
  print(ans[N-1] ? *ans[N-1] : -1ll);

  return 0;
}
