#include <bits/stdc++.h>

#ifdef DEBUG
#include <Mylib/Debug/debug.cpp>
#else
#define dump(...) ((void)0)
#endif

template <typename T, typename U>
bool chmin(T &a, const U &b){
  return (a > b ? a = b, true : false);
}

template <typename T, typename U>
bool chmax(T &a, const U &b){
  return (a < b ? a = b, true : false);
}

template <typename T, size_t N, typename U>
void fill_array(T (&a)[N], const U &v){
  std::fill((U*)a, (U*)(a + N), v);
}

template <typename T>
auto make_vector(int n, int m, const T &value){
  return std::vector<std::vector<T>>(n, std::vector<T>(m, value));
}

template <typename T>
std::ostream& operator<<(std::ostream &s, const std::vector<T> &a){
  for(auto it = a.begin(); it != a.end(); ++it){
    if(it != a.begin()) s << " ";
    s << *it;
  }
  return s;
}

template <typename T>
std::istream& operator>>(std::istream &s, std::vector<T> &a){
  for(auto &x : a) s >> x;
  return s;
}

/**
 * @title Basic graph
 * @docs graph.md
 */
template <typename T>
struct Edge{
  int from, to;
  T cost;
  int index = -1;
  Edge(){}
  Edge(int from, int to, T cost): from(from), to(to), cost(cost){}
  Edge(int from, int to, T cost, int index): from(from), to(to), cost(cost), index(index){}
};

template <typename T>
struct Graph{
  using weight_type = T;
  using edge_type = Edge<T>;
  
  std::vector<std::vector<Edge<T>>> data;

  auto& operator[](size_t i){return data[i];}
  const auto& operator[](size_t i) const {return data[i];}
  
  auto begin() const {return data.begin();}
  auto end() const {return data.end();}

  Graph(){}
  Graph(int N): data(N){}

  bool empty() const {return data.empty();}
  int size() const {return data.size();}

  void add_edge(int i, int j, T w, int index = -1){
    data[i].emplace_back(i, j, w, index);
  }
  
  void add_undirected(int i, int j, T w, int index = -1){
    add_edge(i, j, w, index);
    add_edge(j, i, w, index);
  }

  template <size_t I, bool DIRECTED = true, bool WEIGHTED = true>
  void read(int M){
    for(int i = 0; i < M; ++i){
      int u, v; std::cin >> u >> v;
      u -= I;
      v -= I;
      T w = 1;
      if(WEIGHTED) std::cin >> w;
      if(DIRECTED) add_edge(u, v, w, i);
      else add_undirected(u, v, w, i);
    }
  }
};

template <typename T>
using Tree = Graph<T>;


/**
 * @title Dijkstra algorithm
 * @docs dijkstra.md
 */
template <typename T>
auto dijkstra(const Graph<T> &graph, std::vector<int> src){
  using P = std::pair<T, int>;
  
  const int n = graph.size();
  std::vector<std::optional<T>> dist(n);
  
  std::vector<bool> check(n, false);
  std::priority_queue<P, std::vector<P>, std::greater<P>> pq;

  for(auto s : src){
    dist[s] = 0;
    pq.emplace(0, s);
  }

  while(not pq.empty()){
    const auto [d, i] = pq.top(); pq.pop();

    if(check[i]) continue;
    check[i] = true;

    for(auto &e : graph[i]){
      if(not dist[e.to]){
        dist[e.to] = d + e.cost;
        pq.emplace(*dist[e.to], e.to);
      }else{
        if(*dist[e.to] > d + e.cost){
          dist[e.to] = d + e.cost;
          if(not check[e.to]) pq.emplace(*dist[e.to], e.to);
        }
      }
    }
  }

  return dist;
}

template <typename T>
class RangeGraph : public Graph<T>{
  using super = Graph<T>;
  
  int k, N;
  int calc_size(int N) const {
    int ret = 1;
    while(ret < N) ret *= 2;
    return ret;
  }

public:
  RangeGraph(int N): Graph<T>(5 * (k = (calc_size(N)))), N(N){
    for(int i = 2; i < 2 * k; ++i){
      super::add_edge(k + (i >> 1), k + i, 0);
      super::add_edge(3 * k + i, 3 * k + (i >> 1), 0);
    }

    for(int i = 0; i < N; ++i){
      super::add_edge(2 * k + i, i, 0);
      super::add_edge(i, 4 * k + i, 0);
    }
  }

  void add_edge(int i, int j, T w){
    super::add_edge(i, j, w);
  }

  void add_edge(int i, std::pair<int, int> p, T w){
    auto [l, r] = p;
    for(l += k, r += k; l < r; l >>= 1, r >>= 1){
      if(l & 1) super::add_edge(i, l + k, w), ++l;
      if(r & 1) --r, super::add_edge(i, r + k, w);
    }
  }

  void add_edge(std::pair<int, int> p, int i, T w){
    auto [l, r] = p;
    for(l += k, r += k; l < r; l >>= 1, r >>= 1){
      if(l & 1) super::add_edge(l + 3 * k, i, w), ++l;
      if(r & 1) --r, super::add_edge(r + 3 * k, i, w);
    }
  }

  void add_edge(std::pair<int, int> p, std::pair<int, int> q, T w){
    int x = super::size();
    super::data.emplace_back();
    int y = super::size();
    super::data.emplace_back();

    add_edge(p, x, 0);
    add_edge(x, y, w);
    add_edge(y, q, 0);
  }
};




namespace solver{
  void init(){
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    std::cout << std::fixed << std::setprecision(12);
    std::cerr << std::fixed << std::setprecision(12);
    std::cin.exceptions(std::ios_base::failbit);
  }
  
  void solve(){
    int N, M; std::cin >> N >> M;
    RangeGraph<int64_t> g(N);
    for(int i = 0; i < M; ++i){
      int L, R, C; std::cin >> L >> R >> C;
      --L;
      g.add_edge({L, R}, {L, R}, C);
    }

    auto ans = dijkstra(g, {0})[N-1];
    
    std::cout << ans.value_or(-1) << "\n";
  }
}

int main(){
  solver::init();
  while(true){
    try{
      solver::solve();
    }catch(const std::istream::failure &e){
      break;
    }
  }
  return 0;
}


Measured memory_bytes: 153308