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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.*;

import java.io.*;
import java.nio.charset.StandardCharsets;

public class Main {
	static class Node {
		int id;
		Map<Integer, Long> edges;

		Node(int id) {
			this.id = id;
			this.edges = new HashMap<>();
		}

		void setEdge(int dst, long c) {
			if (!this.edges.containsKey(dst)) {
				this.edges.put(dst, c);
			} else if (this.edges.get(dst) > c) {
				this.edges.put(dst, c);
			}
		}

		Set<Edge> getEdges() {
			Set<Edge> set = new HashSet<>();
			for (Integer dst : this.edges.keySet()) {
				set.add(new Edge(this.id, dst, this.edges.get(dst)));
			}
			this.edges.clear();
			return set;
		}
	}

	static class Edge {
		int src, dst;
		long c;

		Edge(int src, int dst, long c) {
			this.src = src;
			this.dst = dst;
			this.c = c;
		}
	}

	public static void main(String[] args) throws IOException {
		InputStreamReader reader = new InputStreamReader(System.in, StandardCharsets.UTF_8);
		BufferedReader in = new BufferedReader(reader);
		int N, M;
		String[] tokens = in.readLine().split(" ");
		N = Integer.parseInt(tokens[0]);
		M = Integer.parseInt(tokens[1]);
		Node[] nodes = new Node[N];
		for (int i = 0; i < N; ++i) {
			nodes[i] = new Node(i);
		}
		// 区間の中間からの処理を可能とするための便宜上の辺を追加
		for( int i = 1; i < N; ++i) {
			nodes[i].setEdge(i-1, 0L);
		}
		for (int i = 0; i < M; ++i) {
			tokens = in.readLine().split(" ");
			int src = Integer.parseInt(tokens[0]) - 1;
			int dst = Integer.parseInt(tokens[1]) - 1;
			long c = Long.parseLong(tokens[2]);
			nodes[src].setEdge(dst, c);
		}
		Queue<Edge> queue = new PriorityQueue<>(new Comparator<Edge>() {
			@Override
			public int compare(Edge o1, Edge o2) {
				return Long.compare(o1.c, o2.c);
			}
		});
		// queueにrootから出ているedgeを追加する
		queue.addAll(nodes[0].getEdges());
		long[] distances = new long[N];
		Arrays.fill(distances, Long.MAX_VALUE / 2);
		distances[0] = 0;
		while (!queue.isEmpty()) {
			Edge edge = queue.poll();
			distances[edge.dst] = Math.min(distances[edge.dst], distances[edge.src] + edge.c);
			queue.addAll(nodes[edge.dst].getEdges());
		}
		if (distances[N - 1] >= Long.MAX_VALUE / 2) {
			System.out.println(-1);
		} else {
			System.out.println(distances[N - 1]);
		}
	}
}