#define _USE_MATH_DEFINES
#include <array>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <complex>
#include <cmath>
#include <numeric>
#include <bitset>
#include <functional>
#include <random>
#include <ctime>

using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}

typedef long long int64;
typedef pair<int, int> ii;
const int64 INF = 1LL << 60;
const int MOD = 1e9 + 7;
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x; }

struct segment_tree {
  struct node;
  using iter = vector<node>::iterator;

  struct node {
    int a, b;
    iter left, right;
    int64 minv, pass;
    void pushup() {
      minv = min(left->minv, right->minv);
    }
    void pushdown() {
      if (pass == INF) return;
      left->update(pass);
      right->update(pass);
      pass = INF;
    }
    void update(int64 pass) {
      minv = min(minv, pass);
      this->pass = min(this->pass, pass);
    }
  };

  vector<node> pool;
  iter last, root;

  iter _build(int a, int b) {
    iter cur = last++;
    cur->a = a;
    cur->b = b;
    cur->minv = cur->pass = INF;
    if (a + 1 == b) {
      if (a == 0) cur->minv = 0;
      return cur;
    }
    cur->left = _build(a, (a + b) / 2);
    cur->right = _build((a + b) / 2, b);
    cur->pushup();
    return cur;
  }

  void init(int n) {
    pool.resize(n * 2);
    last = pool.begin();
    root = _build(0, n);
  }

  void insert(iter cur, ii range, int64 pass) {
    if (cur->a >= range.first && cur->b <= range.second) {
      cur->update(pass);
      return;
    }
    cur->pushdown();
    if ((cur->a + cur->b) / 2 > range.first) {
      insert(cur->left, range, pass);
    }
    if ((cur->a + cur->b) / 2 < range.second) {
      insert(cur->right, range, pass);
    }
    cur->pushup();
  }

  int64 query(iter cur, ii range) {
    if (cur->a >= range.first && cur->b <= range.second) {
      return cur->minv;
    }
    cur->pushdown();
    int64 ret = INF;
    if ((cur->a + cur->b) / 2 > range.first) {
      ret = min(ret, query(cur->left, range));
    }
    if ((cur->a + cur->b) / 2 < range.second) {
      ret = min(ret, query(cur->right, range));
    }
    return ret;
  }
};

struct Edge {
  int L, R, c;
  bool operator <(const Edge& rhs) const {
    return L < rhs.L;
  }
};

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  vector<Edge> e(m);
  for (int i = 0; i < m; ++i) {
    scanf("%d%d%d", &e[i].L, &e[i].R, &e[i].c);
    --e[i].L;
  }
  sort(e.begin(), e.end());
  segment_tree st;
  st.init(n);
  for (int i = 0; i < m; ++i) {
    int64 best = st.query(st.root, ii{e[i].L, e[i].L + 1});
    st.insert(st.root, ii{e[i].L, e[i].R}, best + e[i].c);
  }
  int64 ret = st.query(st.root, ii{n - 1, n});
  if (ret == INF) ret = -1;
  printf("%lld\n", ret);
  return 0;
}


Measured memory_bytes: 9088