#include <bits/stdc++.h>
using namespace std;
using lint = long long;
constexpr int MOD = 1000000007, INF = 1010101010;
constexpr lint LINF = 1LL << 60;
template <class T>
ostream &operator<<(ostream &os, const vector<T> &vec) {
  for (const auto &e : vec) os << e << (&e == &vec.back() ? "" : " ");
  return os;
}
template <class T>
struct Edge {
  int to;
  T cost;
  Edge() {}
  Edge(int to, T cost) : to(to), cost(cost) {}
  bool operator>(const Edge &r) const { return this->cost > r.cost; }
};
template <class T>
vector<T> Dijkstra(const vector<vector<Edge<T>>> &edges, const int st) {
  const int V = (int)edges.size();
  const T inf = numeric_limits<T>::max() / 2;
  vector<T> cost(V, inf);
  cost[st] = 0;
  priority_queue<Edge<T>, vector<Edge<T>>, greater<Edge<T>>> pq;
  pq.emplace(st, cost[st]);
  while (!pq.empty()) {
    Edge<T> now(pq.top().to, pq.top().cost);
    pq.pop();
    if (cost[now.to] < now.cost) continue;
    for (const Edge<T> &e : edges[now.to]) {
      T tmp_cost = now.cost + e.cost;
      if (cost[e.to] > tmp_cost) {
        cost[e.to] = tmp_cost;
        pq.emplace(e.to, cost[e.to]);
      }
    }
  }
  return cost;
}
int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  vector<vector<Edge<lint>>> edges(N);
  for (int i = 0; i < M; i++) {
    lint u, v, len;
    cin >> u >> v >> len;
    u--, v--;
    edges[u].emplace_back(v, len);
  }
  for (int i = 0; i < N - 1; i++) edges[i + 1].emplace_back(i, 0);
  lint ans = Dijkstra(edges, 0)[N - 1];
  if (ans > LINF / 2)
    cout << ans << "\n";
  else
    cout << -1 << "\n";
  return 0;
}
