macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { let mut $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { let $ var = $ iter . next ( ) . unwrap ( ) . parse ::< usize > ( ) . unwrap ( ) ; input_inner ! { $ iter $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }
trait Monoid {
    type T: Clone + PartialEq;
    fn identity(&self) -> Self::T;
    fn binary_operate(&self, x: &Self::T, y: &Self::T) -> Self::T;
}
struct LazySegmentTree<
    M1: Monoid,
    M2: Monoid,
    F: Fn(&M1::T, &M2::T) -> M1::T,
    G: Fn(&M2::T, usize) -> M2::T,
> {
    n: usize,
    seg: Vec<M1::T>,
    lazy: Vec<M2::T>,
    monoid1: M1,
    monoid2: M2,
    operate: F,
    propagare: G,
}
impl<M1: Monoid, M2: Monoid, F: Fn(&M1::T, &M2::T) -> M1::T, G: Fn(&M2::T, usize) -> M2::T>
    LazySegmentTree<M1, M2, F, G>
{
    fn new(
        n: usize,
        monoid1: M1,
        monoid2: M2,
        operate: F,
        propagare: G,
    ) -> LazySegmentTree<M1, M2, F, G> {
        let n = 1 << format!("{:b}", n - 1).len();
        let seg = vec![monoid1.identity(); 2 * n - 1];
        let lazy = vec![monoid2.identity(); 2 * n - 1];
        LazySegmentTree {
            n: n,
            seg: seg,
            lazy: lazy,
            monoid1: monoid1,
            monoid2: monoid2,
            operate: operate,
            propagare: propagare,
        }
    }
    fn eval(&mut self, k: usize, len: usize) {
        if self.lazy[k] != self.monoid2.identity() {
            if k * 2 + 1 < self.n * 2 - 1 {
                self.lazy[2 * k + 1] = self
                    .monoid2
                    .binary_operate(&self.lazy[2 * k + 1], &self.lazy[k]);
                self.lazy[2 * k + 2] = self
                    .monoid2
                    .binary_operate(&self.lazy[2 * k + 2], &self.lazy[k]);
            }
            self.seg[k] = (self.operate)(&self.seg[k], &(self.propagare)(&self.lazy[k], len));
            self.lazy[k] = self.monoid2.identity();
        }
    }
    fn update_inner(
        &mut self,
        l: usize,
        r: usize,
        x: M2::T,
        k: usize,
        a: usize,
        b: usize,
    ) -> M1::T {
        self.eval(k, b - a);
        if b <= l || r <= a {
            self.seg[k].clone()
        } else if l <= a && b <= r {
            self.lazy[k] = self.monoid2.binary_operate(&self.lazy[k], &x);
            (self.operate)(&self.seg[k], &(self.propagare)(&self.lazy[k], b - a))
        } else {
            let lx = self.update_inner(l, r, x.clone(), k * 2 + 1, a, (a + b) / 2);
            let rx = self.update_inner(l, r, x, k * 2 + 2, (a + b) / 2, b);
            let res = self.monoid1.binary_operate(&lx, &rx);
            self.seg[k] = res.clone();
            res
        }
    }
    fn update(&mut self, l: usize, r: usize, x: M2::T) -> M1::T {
        let n = self.n;
        self.update_inner(l, r, x, 0, 0, n)
    }
    fn query_inner(&mut self, l: usize, r: usize, k: usize, a: usize, b: usize) -> M1::T {
        self.eval(k, b - a);
        if b <= l || r <= a {
            self.monoid1.identity()
        } else if l <= a && b <= r {
            self.seg[k].clone()
        } else {
            let lx = self.query_inner(l, r, k * 2 + 1, a, (a + b) / 2);
            let rx = self.query_inner(l, r, k * 2 + 2, (a + b) / 2, b);
            self.monoid1.binary_operate(&lx, &rx)
        }
    }
    fn query(&mut self, l: usize, r: usize) -> M1::T {
        let n = self.n;
        self.query_inner(l, r, 0, 0, n)
    }
}
struct MaxMonoid<T: Ord + Clone> {
    max: T,
}
impl<T: Ord + Clone> MaxMonoid<T> {
    fn new(max: T) -> MaxMonoid<T> {
        MaxMonoid { max: max }
    }
}
impl<T: Ord + Clone> Monoid for MaxMonoid<T> {
    type T = T;
    fn identity(&self) -> T {
        self.max.clone()
    }
    fn binary_operate(&self, x: &T, y: &T) -> T {
        std::cmp::max(x, y).clone()
    }
}
struct AnyMonoid<T: Clone, F: Fn(&T, &T) -> T> {
    id: T,
    op: F,
}
impl<T: Clone, F: Fn(&T, &T) -> T> AnyMonoid<T, F> {
    fn new(id: T, op: F) -> AnyMonoid<T, F> {
        AnyMonoid { id: id, op: op }
    }
}
impl<T: Clone + PartialEq, F: Fn(&T, &T) -> T> Monoid for AnyMonoid<T, F> {
    type T = T;
    fn identity(&self) -> T {
        self.id.clone()
    }
    fn binary_operate(&self, x: &T, y: &T) -> T {
        (self.op)(x, y)
    }
}
fn main() {
    input! { n, m, mut lra: [(usize, usize, isize); m] };
    lra.sort_by_key(|&(l, r, _a)| (r, l));
    let mut dp = LazySegmentTree::new(
        n + 1,
        MaxMonoid::new(0),
        AnyMonoid::new(0isize, |&x, &y| x + y),
        |&x, &y| x + y,
        |&x, _y| x,
    );
    let mut j = 0;
    for i in 1..(n + 1) {
        let d = dp.query(0, i);
        dp.update(i, i + 1, d);
        while j < m && lra[j].1 <= i {
            dp.update(lra[j].0, i + 1, lra[j].2);
            j += 1;
        }
    }
    println!("{}", dp.query(0, n + 1));
}


Measured memory_bytes: 23800