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)

#pragma GCC optimize("Ofast,fast-math,unroll-loops")

#include <bits/stdc++.h>

#define int ll
//#define double long double
//#define endl '\n'
#define all(C) (C).begin(), (C).end()
#define rall(C) (C).rbegin(), (C).rend()
#define mp make_pair
#define pb emplace_back
#define dbg(x) cerr << #x << " : " << x << endl
#define PI 3.14159265358979

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pii = pair <int, int>;
using pld = pair <ld, ld>;

/*
const ll MAX_MEM = 7e8;
char MEM[MAX_MEM];
ll MEM_POS = 0;
void* operator new(size_t x)
{
    auto ret = MEM + MEM_POS;
    MEM_POS += x;
    assert(MEM_POS < MAX_MEM);
    return ret;
}
void operator delete(void*)
{}
*/

template <class T>
istream& operator>> (istream &in, vector <T> &a)
{
    for (auto &i : a)
        in >> i;
    return in;
}

template <class T>
ostream& operator<< (ostream &out, vector <T> a)
{
    for (auto &i : a)
        out << i << ' ';
    return out;
}

template <class T, class U>
istream& operator>> (istream &in, pair <T, U> &p)
{
    in >> p.first >> p.second;
    return in;
}

template <class T, class U>
ostream& operator<< (ostream &out, pair <T, U> p)
{
    out << p.first << " " << p.second << " ";
    return out;
}

inline void Start()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    //freopen(".in", "r", stdin);
    //freopen(".out", "w", stdout);
}

struct node
{
    int val;
    int vl, vr;
    node *l = 0, *r = 0;
    node() {}
    node(int tl, int tr, vector <int> &a)
    {
        vl = tl, vr = tr;
        if (vr - vl == 1)
        {
            val = a[vl];
            return;
        }
        int vm = (vl + vr) >> 1;
        l = new node(vl, vm, a), r = new node(vm, vr, a);
        val = min(l->val, r->val);
    }
    int get(int ql, int qr)
    {
        if (vl == ql && vr == qr)
            return val;
        int vm = (vl + vr) >> 1;
        if (qr <= vm)
            return l->get(ql, qr);
        if (ql >= vm)
            return r->get(ql, qr);
        return min(l->get(ql, vm), r->get(vm, qr));
    }
    void change(int pos, int x)
    {
        if (vr - vl == 1)
        {
            val = x;
            return;
        }
        int vm = (vl + vr) >> 1;
        if (pos < vm)
            l->change(pos, x);
        else
            r->change(pos, x);
        val = min(l->val, r->val);
    }
};

signed main()
{
    Start();
    int n, m;
    cin >> n >> m;
#define x first
#define y second
    vector <pair <pii, int>> a(m);
    for (int i = 0; i < m; ++i)
    {
        int l, r, c;
        cin >> l >> r >> c, --l, --r;
        a[i].x.x = r;
        a[i].x.y = l;
        a[i].y = c;
    }
    sort(all(a));
    const int INF = 1e18;
    vector <int> d(n, INF);
    d[0] = 0;
    node *t = new node(0, n, d);
    for (auto rlc : a)
    {
        int r = rlc.x.x, l = rlc.x.y, c = rlc.y;
        int val = t->get(l, r + 1);
        val += c;
        if (d[r] > val)
            d[r] = val, t->change(r, val);
    }
    if (d[n - 1] == INF)
        cout << -1;
    else
        cout << d[n - 1];
    return 0;
}