#include <bits/stdc++.h>
using namespace std;
struct Dijkstra {
  long long int INF = 1000000000000000009;
  long long int MAX_V = 1000000;
  long long int st = -1;
  struct edge {
    long long int to, cost;
  };
  vector<vector<edge>> G;
  vector<long long int> pre, d;
  priority_queue<pair<long long int, long long int>,
                 vector<pair<long long int, long long int>>,
                 greater<pair<long long int, long long int>>>
      que;
  Dijkstra(long long int s) {
    G.resize(s + 2);
    pre.resize(s + 2, -1);
    d.resize(s + 2, INF);
  }
  inline void insert(long long int a, long long int b, long long int c) {
    G[a].push_back(edge{b, c});
  }
  void init() {
    for (int i = 0; i < d.size(); i++) pre[i] = -1, d[i] = INF;
  }
  void dijkstra(int start) {
    init();
    st = start;
    d[start] = 0;
    que.push(pair<long long int, long long int>(0, start));
    while (!que.empty()) {
      pair<long long int, long long int> p_now = que.top();
      que.pop();
      long long int v = p_now.second;
      if (d[v] < p_now.first) continue;
      for (int i = 0; i < G[v].size(); i++) {
        edge e = G[v][i];
        if (d[e.to] > d[v] + e.cost) {
          d[e.to] = d[v] + e.cost;
          pre[e.to] = v;
          que.push(pair<long long int, long long int>(d[e.to], e.to));
        }
      }
    }
  }
  vector<long long int> get_path(int now) {
    vector<long long int> ret;
    while (now != -1) {
      ret.push_back(now);
      now = pre[now];
    }
    return ret;
  }
};
struct Merge {
  map<long long int, long long int> l, r;
  long long int INF = 1000000000000000000, tmp = 0;
  vector<long long int> remove(long long int a, long long int b) {
    if (a > b) swap(a, b);
    auto y = r.lower_bound(a);
    if (r.size() == 0 || y == r.end()) return vector<long long int>{a, b};
    auto x = --l.lower_bound(b + 1);
    long long int to = (*x).second;
    while (true) {
      bool br = false;
      if ((*y).second == to) br = true;
      long long int now_y = (*y).first, now_x = (*x).first;
      a = min(now_x, a), b = max(now_y, b);
      y++, x--;
      l.erase(now_x), r.erase(now_y);
      if (br) break;
    }
    return vector<long long int>{a, b};
  }
  void merge(long long int a, long long int b) {
    tmp++;
    vector<long long int> t = remove(a, b);
    l.emplace(t[0], tmp), r.emplace(t[1], tmp);
  }
  vector<long long int> get(long long int a) {
    auto left = l.upper_bound(a);
    auto right = r.lower_bound(a);
    if (left == l.begin()) return vector<long long int>{INF, INF};
    left--;
    if ((*right).first >= a && (*left).first <= a)
      return vector<long long int>{(*left).first, (*right).first};
    else
      return vector<long long int>{INF, INF};
  }
  bool same(long long int a, long long int b) { return get(a)[0] == get(b)[0]; }
  vector<vector<long long int>> check(int i = -1) {
    if (i == -1) i = l.size();
    auto itl = l.begin(), itr = r.begin();
    vector<vector<long long int>> ret =
        vector<vector<long long int>>(0, vector<long long int>(2, 0));
    for (int j = 0; j < i && itl != l.end(); j++, itl++, itr++) {
      ret.push_back(vector<long long int>{(*itl).first, (*itr).first});
    }
    return ret;
  }
};
int main(int argc, char const *argv[]) {
  long long int a, b, c, n, m;
  std::cin >> n >> m;
  Dijkstra dk(1000000);
  Merge mg;
  for (int i = 0; i < m; i++) {
    std::cin >> a >> b >> c;
    mg.merge(a, b);
    dk.insert(a, b, c);
  }
  vector<vector<long long int>> t = mg.check();
  for (int i = 0; i < t.size(); i++) {
    for (int j = t[i][1]; j > t[i][0]; j--) {
      dk.insert(j, j - 1, 0);
    }
  }
  dk.dijkstra(1);
  std::cout << (dk.d[n] == 1000000000000000009 ? -1 : dk.d[n]) << '\n';
  return 0;
}
