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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

static class Program
{
    class PriorityQueue<T>
    {
        private readonly List<T> m_list;
        private readonly Func<T, T, int> m_compare;

        public PriorityQueue(int capacity, Func<T, T, int> compare)
        {
            m_list = new List<T>(capacity);
            m_compare = compare;
            Count = 0;
        }
        private int Add(T value)
        {
            if (Count == m_list.Count)
            {
                m_list.Add(value);
            }
            else
            {
                m_list[Count] = value;
            }
            return Count++;
        }
        private void Swap(int a, int b)
        {
            T tmp = m_list[a];
            m_list[a] = m_list[b];
            m_list[b] = tmp;
        }
        public void Enqueue(T value)
        {
            int c = Add(value);
            while (c > 0)
            {
                int p = (c - 1) / 2;
                if (m_compare(m_list[c], m_list[p]) < 0) { Swap(p, c); } else { break; }
                c = p;
            }
        }
        public T Dequeue()
        {
            T value = m_list[0];
            m_list[0] = m_list[--Count];
            int p = 0;
            while (true)
            {
                int c1 = p * 2 + 1;
                int c2 = p * 2 + 2;
                if (c1 >= Count) { break; }
                int c = (c2 >= Count || m_compare(m_list[c1], m_list[c2]) < 0) ? c1 : c2;
                if (m_compare(m_list[c], m_list[p]) < 0) { Swap(p, c); } else { break; }
                p = c;
            }
            return value;
        }
        public int Count { get; private set; }
    }

    static long Solve(int N, int M, int[][] values)
    {
        var edges = new Dictionary<int, int>[N];
        for (int i = 0; i < N; ++i)
        {
            edges[i] = new Dictionary<int, int>();
            if (i > 0) { edges[i][i - 1] = 0; }
        }
        foreach (var v in values)
        {
            int L = v[0] - 1;
            int R = v[1] - 1;
            int C = v[2];
            if (!edges[L].ContainsKey(R)) { edges[L][R] = int.MaxValue; }
            edges[L][R] = Math.Min(C, edges[L][R]);
        }
        const long INF = long.MaxValue / 2;
        var d = Enumerable.Repeat(INF, N).ToArray();
        var q = new PriorityQueue<int>(N, (a, b) => (d[a].CompareTo(d[b])));
        d[0] = 0;
        q.Enqueue(0);
        while (q.Count > 0)
        {
            int a = q.Dequeue();
            foreach (var edge in edges[a])
            {
                int b = edge.Key;
                int c = edge.Value;
                if (d[a] + c < d[b])
                {
                    d[b] = d[a] + c;
                    q.Enqueue(b);
                }
            }
        }
        return (d[N - 1] < INF) ? d[N - 1] : -1;
    }

    static void Main(string[] args)
    {
        int[] V1 = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
        int N = V1[0], M = V1[1];
        var values = new int[M][];
        for (int i = 0; i < M; ++i)
        {
            values[i] = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
        }
        Console.WriteLine(Solve(N, M, values));
    }
}