#include <bits/stdc++.h>
using namespace std;
typedef priority_queue<long long, vector<long long>> decendingQueue;
typedef priority_queue<long long, vector<long long>, greater<long long>>
    ascendingQueue;
const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const long long INF = 9 * 1e18;
const long long MOD = 1e9 + 7;
long long gcd(long long m, long long n) {
  if (m < n) return gcd(n, m);
  if (n == 0) return m;
  return gcd(n, m % n);
}
long long lcm(long long m, long long n) { return m * (n / gcd(m, n)); }
const int mod = 1000000007;
struct mint {
  long long x;
  mint(long long x = 0) : x((x % mod + mod) % mod) {}
  mint &operator+=(const mint a) {
    if ((x += a.x) >= mod) x -= mod;
    return *this;
  }
  mint &operator-=(const mint a) {
    if ((x += mod - a.x) >= mod) x -= mod;
    return *this;
  }
  mint &operator*=(const mint a) {
    (x *= a.x) %= mod;
    return *this;
  }
  mint operator+(const mint a) const {
    mint res(*this);
    return res += a;
  }
  mint operator-(const mint a) const {
    mint res(*this);
    return res -= a;
  }
  mint operator*(const mint a) const {
    mint res(*this);
    return res *= a;
  }
  mint pow(long long t) const {
    if (!t) return 1;
    mint a = pow(t >> 1);
    a *= a;
    if (t & 1) a *= *this;
    return a;
  }
  mint inv() const { return pow(mod - 2); }
  mint &operator/=(const mint a) { return (*this) *= a.inv(); }
  mint operator/(const mint a) const {
    mint res(*this);
    return res /= a;
  }
};
struct combination {
  vector<mint> fact, ifact;
  combination(int n) : fact(n + 1), ifact(n + 1) {
    assert(n < mod);
    fact[0] = 1;
    for (int i = 1; i <= n; ++i) fact[i] = fact[i - 1] * i;
    ifact[n] = fact[n].inv();
    for (int i = n; i >= 1; --i) ifact[i - 1] = ifact[i] * i;
  }
  mint operator()(int n, int k) {
    if (k < 0 || k > n) return 0;
    return fact[n] * ifact[k] * ifact[n - k];
  }
};
vector<long long> SieveOfEratosthenes(int max) {
  vector<long long> sieve;
  vector<long long> primes;
  for (int i = 1; i < max + 1; ++i) {
    sieve.push_back(i);
  }
  sieve[0] = 0;
  for (int i = 2; i < max + 1; ++i) {
    if (sieve[i - 1] != 0) {
      primes.push_back(sieve[i - 1]);
      for (int j = 2 * sieve[i - 1]; j < max + 1; j += sieve[i - 1]) {
        sieve[j - 1] = 0;
      }
    }
  }
  return primes;
}
class UnionFindTree {
 private:
  vector<int> par;
  vector<int> rnk;
  vector<int> siz;

 public:
  UnionFindTree(int n) {
    par.assign(n, -1);
    rnk.assign(n, -1);
    siz.assign(n, -1);
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      rnk[i] = 0;
      siz[i] = 1;
    }
  }
  int find(int x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (rnk[x] < rnk[y]) {
      par[x] = y;
      siz[y] += siz[x];
    } else {
      par[y] = x;
      siz[x] += siz[y];
      if (rnk[x] == rnk[y]) ++rnk[x];
    }
  }
  int size(int x) {
    x = find(x);
    return siz[x];
  }
};
class Edge {
 public:
  long long from;
  long long to;
  long long cost;
  Edge() {}
  Edge(long long from, long long to, long long cost) {
    this->from = from;
    this->to = to;
    this->cost = cost;
  }
  bool operator<(const Edge &edge) const { return cost < edge.cost; }
};
class Graph {
 public:
  long long nodes;
  vector<Edge> edges;
  Graph() {}
  Graph(long long nodes) { this->nodes = nodes; }
  void addEdge(long long from, long long to, long long cost) {
    this->edges.push_back(Edge(from, to, cost));
  }
};
class Kruskal {
 private:
  Graph graph;
  vector<Edge> MinimumSpanningTree;
  long long minimumCost;
  void searchMinimumSpanningTree() {
    UnionFindTree uf(graph.nodes);
    sort((graph.edges).begin(), (graph.edges).end());
    for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
         (edge)++) {
      if (!uf.same(edge->from, edge->to)) {
        uf.unite(edge->from, edge->to);
        MinimumSpanningTree.push_back(*edge);
      }
    }
  }

 public:
  Kruskal(Graph graph) { this->graph = graph; }
  long long getMinimumSpanningTreeCost() {
    searchMinimumSpanningTree();
    long long cost = 0;
    for (auto(it) = (MinimumSpanningTree).begin();
         (it) != (MinimumSpanningTree).end(); (it)++) {
      cost += it->cost;
    }
    return cost;
  }
};
class Dijkstra {
 private:
  Graph graph;
  map<long long, vector<Edge>> fromPaths;
  vector<long long> distances;
  vector<long long> srcs;

 public:
  Dijkstra(Graph graph) {
    this->graph = graph;
    for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
         (edge)++) {
      fromPaths[edge->from].push_back(*edge);
    }
  }
  void searchMinimumPathFrom(long long src) {
    distances = vector<long long>(graph.nodes + 1, INF);
    srcs = vector<long long>(graph.nodes + 1, INF);
    priority_queue<long long> pq;
    distances[src] = 0;
    srcs[src] = -1;
    pq.push(src);
    while (!pq.empty()) {
      int u = pq.top();
      pq.pop();
      for (auto(edge) = (fromPaths[u]).begin(); (edge) != (fromPaths[u]).end();
           (edge)++) {
        int v = edge->to;
        long long w = edge->cost;
        if (distances[v] > distances[u] + w) {
          distances[v] = distances[u] + w;
          srcs[v] = u;
          pq.push(v);
        }
      }
    }
  };
  long long getDistance(long long n) { return distances[n]; }
  long long getFrom(long long n) { return srcs[n]; }
};
class BellmanFord {
 private:
  Graph graph;
  vector<bool> hasNegativeCycles;
  vector<long long> distances;
  vector<long long> srcs;

 public:
  BellmanFord(Graph graph) {
    long long nodes = graph.nodes + 1;
    this->graph = graph;
    distances = vector<long long>(nodes, INF);
    hasNegativeCycles = vector<bool>(nodes, false);
  }
  void searchMinimumPathFrom(long long src) {
    distances[src] = 0;
    for (long long i = 0; i < graph.nodes - 1; i++) {
      for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
           (edge)++) {
        long long u = edge->from;
        long long v = edge->to;
        long long w = edge->cost;
        if (distances[u] != INF) {
          distances[v] = min(distances[v], distances[u] + w);
        }
      }
    }
    for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
         (edge)++) {
      long long u = edge->from;
      long long v = edge->to;
      long long w = edge->cost;
      if (distances[u] == INF) {
        continue;
      }
      if (distances[u] + w < distances[v]) {
        hasNegativeCycles[v] = true;
      }
    }
    for (long long i = 0; i < graph.nodes; i++) {
      for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
           (edge)++) {
        long long u = edge->from;
        long long v = edge->to;
        long long w = edge->cost;
        if (distances[u] == INF) {
          continue;
        }
        distances[v] = min(distances[v], distances[u] + w);
        if (hasNegativeCycles[u] == true) {
          hasNegativeCycles[v] = true;
        }
      }
    }
  }
  long long getDistance(long long n) { return distances[n]; }
  bool hasNegativeCycle(long long n) { return hasNegativeCycles[n]; }
  long long getFrom(long long n) { return srcs[n]; }
};
class WarshallFloyd {
 private:
  Graph graph;
  int nodes = this->graph.nodes + 1;
  vector<vector<long long>> distances;

 public:
  WarshallFloyd(Graph graph) {
    this->graph = graph;
    nodes = this->graph.nodes + 1;
    this->distances =
        vector<vector<long long>>(nodes, vector<long long>(nodes, INF));
    for (auto(edge) = (graph.edges).begin(); (edge) != (graph.edges).end();
         (edge)++) {
      int from = edge->from;
      int to = edge->to;
      int cost = edge->cost;
      distances[from][to] = cost;
    }
  }
  void searchMinimumPath() {
    for (int k = 0; k < nodes; k++) {
      for (int i = 0; i < nodes; i++) {
        for (int j = 0; j < nodes; j++) {
          if (distances[i][k] == INF || distances[k][j] == INF) {
            continue;
          }
          if (distances[i][k] + distances[k][j] < distances[i][j]) {
            distances[i][j] = distances[i][k] + distances[k][j];
          }
        }
      }
    }
  }
  long long getDistance(int from, int to) { return distances[from][to]; }
};
void solve(long long N, long long M, std::vector<long long> L,
           std::vector<long long> R, std::vector<long long> C) {
  Graph g(N);
  for (int(i) = (1); (i) < (N); ++(i)) {
    g.addEdge(i, i - 1, 0);
  }
  for (int(i) = (0); (i) < (M); ++(i)) {
    g.addEdge(--L[i], --R[i], C[i]);
  }
  Dijkstra dikjstra(g);
  dikjstra.searchMinimumPathFrom(0);
  long long dist = dikjstra.getDistance(N - 1);
  if (dist != INF) {
    cout << dist << endl;
  } else {
    cout << -1 << endl;
  }
}
int main() {
  long long N;
  scanf("%lld", &N);
  long long M;
  scanf("%lld", &M);
  std::vector<long long> L(M);
  std::vector<long long> R(M);
  std::vector<long long> C(M);
  for (int i = 0; i < M; i++) {
    scanf("%lld", &L[i]);
    scanf("%lld", &R[i]);
    scanf("%lld", &C[i]);
  }
  solve(N, M, std::move(L), std::move(R), std::move(C));
  return 0;
}
