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 Rust (1.42.0) (judge verdict: Accepted)

// ---------- begin chmin, chmax ----------
trait ChangeMinMax {
    fn chmin(&mut self, x: Self) -> bool;
    fn chmax(&mut self, x: Self) -> bool;
}

impl<T: PartialOrd> ChangeMinMax for T {
    fn chmin(&mut self, x: Self) -> bool {
        *self > x && {
            *self = x;
            true
        }
    }
    fn chmax(&mut self, x: Self) -> bool {
        *self < x && {
            *self = x;
            true
        }
    }
}
// ---------- end chmin, chmax ----------
// ---------- begin segment tree closure ----------
struct SegmentTree<T> {
    size: usize,
    val: Vec<Option<T>>,
}

#[allow(dead_code)]
impl<T> SegmentTree<T> 
where
    T: Clone
{
    fn new(size: usize) -> Self {
        let size = size.next_power_of_two();
        SegmentTree {
            size: size,
            val: (0..(2 * size)).map(|_| None).collect(),
        }
    }
    fn build_by<F>(a: &[T], mut f: F) -> Self
    where
        F: FnMut(&T, &T) -> T,
    {
        let size = a.len().next_power_of_two();
        let mut val = (0..(2 * size)).map(|_| None).collect::<Vec<_>>();
        for (v, a) in val[size..].iter_mut().zip(a.iter()) {
            *v = Some(a.clone());
        }
        for x in (1..size).rev() {
            val[x] = match (val[2 * x].as_ref(), val[2 * x + 1].as_ref()) {
                (Some(l), Some(r)) => Some(f(l, r)),
                _ => val[2 * x].clone().or_else(|| val[2 * x + 1].clone()),
            };
        }
        SegmentTree {
            size: size,
            val: val,
        }
    }
    fn update<F>(&mut self, x: usize, val: Option<T>, mut f: F)
    where
        F: FnMut(&T, &T) -> T,
    {
        assert!(x < self.size);
        let mut x = x + self.size;
        self.val[x] = val;
        let val = &mut self.val;
        x >>= 1;
        while x > 0 {
            val[x] = match (val[2 * x].as_ref(), val[2 * x + 1].as_ref()) {
                (Some(l), Some(r)) => Some(f(l, r)),
                _ => val[2 * x].clone().or_else(|| val[2 * x + 1].clone()),
            };
            x >>= 1;
        }
    }
    fn query<F>(&self, l: usize, r: usize, mut f: F)
    where
        F: FnMut(&T),
    {
        assert!(l <= r && r <= self.size);
        let mut l = self.size + l;
        let mut r = self.size + r;
        let val = &self.val;
        while l < r {
            if l & 1 == 1 {
                val[l].as_ref().map(|p| f(p));
                l += 1;
            }
            if r & 1 == 1 {
                r -= 1;
                val[r].as_ref().map(|p| f(p));
            }
            l >>= 1;
            r >>= 1;
        }
    }
}
// ---------- end segment tree closure ----------

use proconio::*;
use proconio::marker::*;
use std::cmp::*;

fn run() {
    input! {
        n: usize,
        m: usize,
        e: [(Usize1, usize, u64); m],
    }
    let ini = (0..n).collect::<Vec<_>>();
    let mut id = n;
    let mut gen = || {
        let v = id;
        id += 1;
        v
    };
    let mut edge = vec![];
    let up = SegmentTree::build_by(&ini, |a, b| {
        let v = gen();
        edge.push((*a, v, 0));
        edge.push((*b, v, 0));
        v
    });
    let down = SegmentTree::build_by(&ini, |a, b| {
        let v = gen();
        edge.push((v, *a, 0));
        edge.push((v, *b, 0));
        v
    });
    for (l, r, c) in e {
        let src = gen();
        let dst = gen();
        edge.push((src, dst, c));
        up.query(l, r, |v| {
            edge.push((*v, src, 0));
        });
        down.query(l, r, |v| {
            edge.push((dst, *v, 0));
        });
    }
    let size = gen();
    let mut cnt = vec![0; size];
    for &(s, _, _) in edge.iter() {
        cnt[s] += 1;
    }
    let mut g = cnt.into_iter().map(|c| Vec::with_capacity(c)).collect::<Vec<_>>();
    for (s, t, c) in edge {
        g[s].push((t, c));
    }
    let mut dp = vec![std::u64::MAX; size];
    dp[0] = 0;
    let mut h = std::collections::BinaryHeap::new();
    h.push(Reverse((0, 0)));
    while let Some(Reverse((d, v))) = h.pop() {
        if d > dp[v] {
            continue;
        }
        for &(u, c) in g[v].iter() {
            let d = d + c;
            if dp[u].chmin(d) {
                h.push(Reverse((d, u)));
            }
        }
    }
    let ans = dp[n - 1];
    if ans == std::u64::MAX {
        println!("-1");
    } else {
        println!("{}", ans);
    }
}

fn main() {
    run();
}