use std::cmp::max;
use std::collections::HashMap;
use std::error::Error;
use std::io;

fn main() {
    if let Err(_e) = run() {
        panic!("failed.");
    };
}

// Max value segment tree.
#[derive(Debug)]
struct SegTree {
    n: usize,
    cached: Vec<i64>,
    values: Vec<i64>,
}

impl SegTree {
    pub fn new(size: i64) -> SegTree {
        let mut n = 1;
        while size + 1 > n {
            n = n * 2;
        }
        SegTree {
            n: n as usize,
            cached: vec![0; n as usize * 2 - 1],
            values: vec![0; n as usize * 2 - 1],
        }
    }

    // (a, b]
    fn add(&mut self, a: usize, b: usize, value: i64) {
        let n = self.n;
        self.add_internal(0, 0, n, a, b, value);
    }
    fn add_internal(&mut self, index: usize, l: usize, r: usize, a: usize, b: usize, value: i64) {
        // println!("{} {} {} {}:{} -> {}", l, r, a, b, index, value);
        if l >= b || r <= a {
            // We always do both side recursively, so it may out of range.
            return;
        }
        if a <= l && r <= b {
            //in the range
            self.cached[index] += value;
            self.values[index] += value;
        } else {
            self.add_internal(index * 2 + 1, l, (l + r) / 2, a, b, value);
            self.add_internal(index * 2 + 2, (l + r) / 2, r, a, b, value);
            self.values[index] =
                self.cached[index] + max(self.values[index * 2 + 1], (self.values[index * 2 + 2]));
        }
    }

    // find max
    fn get(&self, a: usize, b: usize) -> i64 {
        return self.get_internal(0, 0, self.n, a, b);
    }

    fn get_internal(&self, index: usize, l: usize, r: usize, a: usize, b: usize) -> i64 {
        if r <= a || l >= b {
            return std::i64::MIN;
        }
        if a <= l && r <= b {
            return self.values[index];
        }

        return self.cached[index]
            + max(
                self.get_internal(index * 2 + 1, l, (l + r) / 2, a, b),
                self.get_internal(index * 2 + 2, (l + r) / 2, r, a, b),
            );
    }

    fn leaf_count(&self) -> usize {
        (self.values.len() + 1) / 2
    }
}

fn run() -> Result<(), Box<Error>> {
    let mut input = String::new();
    io::stdin().read_line(&mut input);
    let n_m: Vec<i64> = input
        .trim()
        .split_whitespace()
        .map(|s| s.parse::<i64>().unwrap())
        .collect();
    let n = n_m[0];
    let m = n_m[1];
    input.clear();
    let mut adds = HashMap::new();
    let mut removes = HashMap::new();
    for i in 0..m {
        let mut input = String::new();
        io::stdin().read_line(&mut input);
        let lra: Vec<i64> = input
            .trim()
            .split_whitespace()
            .map(|s| s.parse::<i64>().unwrap())
            .collect();
        let values = adds.entry(lra[0]).or_insert(0);
        *values += lra[2];
        let remove_values = removes.entry(lra[1]).or_insert_with(Vec::new);
        remove_values.push((lra[0], lra[2]));
        input.clear();
    }
    let mut tree = SegTree::new(n);
    let mut result = 0;
    for i in 1..n + 1 {
        for &add_values in adds.get(&i) {
            tree.add(0, i as usize, add_values);
        }
        let tmp_max = tree.get(0, i as usize);
        result = max(result, tmp_max);
        tree.add(i as usize, (i + 1) as usize, tmp_max);
        // println!(">>>>after add {:?} = {:?}", i, tree);
        for remove_values in removes.get(&i) {
            for &(l, a) in remove_values {
                tree.add(0, l as usize, -a);
                // println!(">>>>after remove {} from {} = {:?}", a, l, tree);
            }
        }
    }
    println!("{}", result);
    Ok(())
}


Measured memory_bytes: 41168