Problem:
Score : 600 points

Problem Statement

We have N points numbered 1 to N arranged in a line in this order.

Takahashi decides to make an undirected graph, using these points as the vertices.
In the beginning, the graph has no edge. Takahashi will do M operations to add edges in this graph.
The i-th operation is as follows:

The operation uses integers L_i and R_i between 1 and N (inclusive), and a positive integer C_i. For every pair of integers (s, t) such that L_i \leq s < t \leq R_i, add an edge of length C_i between Vertex s and Vertex t.

The integers L_1, ..., L_M, R_1, ..., R_M, C_1, ..., C_M are all given as input.

Takahashi wants to solve the shortest path problem in the final graph obtained. Find the length of the shortest path from Vertex 1 to Vertex N in the final graph.

Constraints

2 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq L_i < R_i \leq N

1 \leq C_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N M
L_1 R_1 C_1
:
L_M R_M C_M

Output

Print the length of the shortest path from Vertex 1 to Vertex N in the final graph.
If there is no shortest path, print -1 instead.

Sample Input 1

4 3
1 3 2
2 4 3
1 4 6

Sample Output 1

5

We have an edge of length 2 between Vertex 1 and Vertex 2, and an edge of length 3 between Vertex 2 and Vertex 4, so there is a path of length 5 between Vertex 1 and Vertex 4.

Sample Input 2

4 2
1 2 1
3 4 2

Sample Output 2

-1

Sample Input 3

10 7
1 5 18
3 4 8
1 3 5
4 7 10
5 9 8
6 10 5
8 10 3

Sample Output 3

28

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#include <boost/range/algorithm.hpp>
#include <boost/range/numeric.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/adaptor/indexed.hpp>

using namespace std;
using namespace boost::adaptors;
using namespace std::string_literals;
using ll = int64_t;
using vecint = vector<int>;
using vecll = vector<ll>;
using boost::irange;

using Data = ll;
constexpr Data INF = 1e15;

struct SegTreeLazy {
  static const int MAX_DEPTH = 18;
  static const int STsize = 1 << MAX_DEPTH;
  Data data[STsize];
  Data lazy[STsize]; int n;
  SegTreeLazy(void) : n(STsize / 2) {
    for(int i:irange(0,STsize)) {
      data[i]=lazy[i]=INF;
    }
  }
  void upd(int fr, int to, Data val) { upd_sub(fr, to, 2*n-2, 0, n, val); }
  Data min_(int fr, int to) { return min_sub(fr, to, 2*n-2, 0, n); }
 private:
  void upd_sub(int fr, int to, int node, int la, int ra, Data val) {
    if (ra<=fr || to<=la) return;
    if (fr<=la && ra<=to) {
      lazy[node] = min(lazy[node], val);
      data[node] = min(data[node], val);
      return;
    }
    data[node] = min(data[node], val);
    upd_sub(fr, to, (node-n)*2+0, la, (la+ra)/2, val);
    upd_sub(fr, to, (node-n)*2+1, (la+ra)/2, ra, val);
  }
  Data min_sub(int fr, int to, int node, int la, int ra) {
    if (ra<=fr || to<=la) return INF;
    if (fr<=la && ra<=to) return min(data[node], lazy[node]);
    Data res = lazy[node];
    res = min(res, min_sub(fr, to, (node-n)*2+0, la, (la+ra)/2));
    res = min(res, min_sub(fr, to, (node-n)*2+1, (la+ra)/2, ra));
    return res;
  }
};

int main()
{
  int n,m;
  cin>>n>>m;
  vector<tuple<ll,ll,ll>> vt;
  for(int i:irange(0,m)) {
    ll l,r,c;
    cin>>l>>r>>c;
    --l;--r;
    vt.emplace_back(l,r,c);
  }
  boost::sort(vt);
  SegTreeLazy stl;
  stl.upd(0,1,0);
  for(auto t:vt) {
    ll l,r,c;
    tie(l,r,c) = t;
    ll d=stl.min_(l,l+1);
    stl.upd(l,r+1,d+c);
  }
  ll res = stl.min_(n-1,n);
  if (res >= INF) {
    cout<<-1<<endl;
  } else {
    cout<<res<<endl;
  }
  return 0;
}