Problem:
Score : 100 points

Problem Statement

Consider a string of length N consisting of 0 and 1.
The score for the string is calculated as follows:

For each i (1 \leq i \leq M), a_i is added to the score if the string contains 1 at least once between the l_i-th and r_i-th characters (inclusive).

Find the maximum possible score of a string.

Constraints

All values in input are integers.

1 \leq N \leq 2 × 10^5

1 \leq M \leq 2 × 10^5

1 \leq l_i \leq r_i \leq N

|a_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N M
l_1 r_1 a_1
l_2 r_2 a_2
:
l_M r_M a_M

Output

Print the maximum possible score of a string.

Sample Input 1

5 3
1 3 10
2 4 -10
3 5 10

Sample Output 1

20

The score for 10001 is a_1 + a_3 = 10 + 10 = 20.

Sample Input 2

3 4
1 3 100
1 1 -10
2 2 -20
3 3 -30

Sample Output 2

90

The score for 100 is a_1 + a_2 = 100 + (-10) = 90.

Sample Input 3

1 1
1 1 -10

Sample Output 3

0

The score for 0 is 0.

Sample Input 4

1 5
1 1 1000000000
1 1 1000000000
1 1 1000000000
1 1 1000000000
1 1 1000000000

Sample Output 4

5000000000

The answer may not fit into a 32-bit integer type.

Sample Input 5

6 8
5 5 3
1 1 10
1 6 -8
3 6 5
3 4 9
5 5 -2
1 3 -6
4 6 -7

Sample Output 5

10

For example, the score for 101000 is a_2 + a_3 + a_4 + a_5 + a_7 = 10 + (-8) + 5 + 9 + (-6) = 10.

Solution in C++14 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include <cstdio>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>

template <class Tp, class BinaryOperation1, class BinaryOperation2>
class segment_tree {
public:
  using binary_operation1 = BinaryOperation1;
  using binary_operation2 = BinaryOperation2;
  using value_type = Tp;

private:
  size_t m, h;
  std::vector<value_type> c, d;
  binary_operation1 op1;  // aggregate
  binary_operation2 op2;  // update

  size_t height(size_t n) const {
    return 64 - __builtin_clzll(n);
  }

  void init_aggregate() {
    for (size_t i = m/2; i-- > 1;)
      c[i] = op1(c[i<<1], c[i<<1|1]);
  }

  void calc(size_t p, size_t k) {
    // called in build()
    c[p] = op1(c[p<<1], c[p<<1|1]);
    if (p < m/2) c[p] = op2(c[p], d[p], k);
  }

  void apply(size_t i, Tp x, size_t k) {
    // called in push() and update()
    c[i] = op2(c[i], x, k);
    if (i < m/2) d[i] = op2(d[i], x);
  }

  void build(size_t i) {
    size_t k = 2;
    for (i += m/2; i > 1; k <<= 1) {
      i >>= 1;
      calc(i, k);
    }
  }

  void push(size_t i) {
    i += m/2;
    for (size_t s = h, k = 1 << (h-1); s > 0; --s, k >>= 1) {
      size_t j = i >> s;
      if (d[j] != op2.identity) {
        apply(j<<1|0, d[j], k);
        apply(j<<1|1, d[j], k);
        d[j] = op2.identity;
      }
    }
  }

public:
  segment_tree(size_t n,
               BinaryOperation1 op1 = BinaryOperation1(),
               BinaryOperation2 op2 = BinaryOperation2()):
    m(2*n), h(height(n)), c(m, op1.identity), d(n, op2.identity),
    op1(op1), op2(op2)
  {}

  segment_tree(size_t n, const value_type& e,
               BinaryOperation1 op1 = BinaryOperation1(),
               BinaryOperation2 op2 = BinaryOperation2()):
    m(2*n), h(height(n)), c(m, e), d(n, op2.identity), op1(op1), op2(op2)
  {
    for (size_t i = n; i < m; ++i) c[i] = e;
    init_aggregate();
  }

  template <class ForwardIt>
  segment_tree(ForwardIt first, ForwardIt last,
               BinaryOperation1 op1 = BinaryOperation1(),
               BinaryOperation2 op2 = BinaryOperation2()):
    m(2*std::distance(first, last)), h(height(m/2)), c(m),
    d(m/2, op2.identity), op1(op1), op2(op2)
  {
    static_assert(std::is_same<Tp, typename ForwardIt::value_type>::value, "");
    for (size_t i = m/2; first != last; ++i) c[i] = *first++;
    init_aggregate();
  }

  void update(size_t l, size_t r, Tp x) {
    push(l);
    push(r-1);
    size_t l0 = l;
    size_t r0 = r;
    l += m/2;
    r += m/2;
    size_t k = 1;
    while (l < r) {
      if (l & 1) apply(l++, x, k);
      if (r & 1) apply(--r, x, k);
      l >>= 1;
      r >>= 1;
      k <<= 1;
    }
    build(l0);
    build(r0-1);
  }

  value_type aggregate(size_t l, size_t r) {
    push(l);
    push(r-1);
    value_type resl = op1.identity;
    value_type resr = op1.identity;
    l += m/2;
    r += m/2;
    while (l < r) {
      if (l & 1) resl = op1(resl, c[l++]);
      if (r & 1) resr = op1(c[--r], resr);
      l >>= 1;
      r >>= 1;
    }
    return op1(resl, resr);
  }

  value_type operator [](size_t k) { return aggregate(k, k+1); }
};

template <class Tp>
struct max {
  Tp identity = std::numeric_limits<Tp>::min() / 4;
  Tp operator ()(const Tp& x, const Tp& y) const {
    return std::max(x, y);
  }
};

template <class Tp>
struct add {
  Tp identity = 0;
  Tp operator ()(const Tp& x, const Tp& y, size_t k = 1) const {
    return x + y;
  }
};

int main() {
  size_t N, M;
  scanf("%zu %zu", &N, &M);

  std::vector<std::tuple<size_t, size_t, intmax_t>> v(M);
  for (auto& vi: v) {
    size_t l, r;
    intmax_t a;
    scanf("%zu %zu %zu", &l, &r, &a);
    vi = std::make_tuple(r, l, a);
  }
  std::sort(v.begin(), v.end());

  segment_tree<intmax_t, max<intmax_t>, add<intmax_t>> dp(N+1, 0);
  for (size_t i = 1; i <= N; ++i) {
    intmax_t cur = dp.aggregate(0, i);
    dp.update(i, i+1, cur-dp[i]);
    for (const auto& vi: v) {
      size_t l, r;
      intmax_t a;
      std::tie(r, l, a) = vi;
      if (r == i)
        dp.update(l, r+1, a);
    }
  }

  printf("%jd\n", dp.aggregate(0, N+1));
}