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# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
using static System.Console;
using System.Text;
using System.IO;
using static System.Math;
namespace AtCoder
{
    class Program
    {
        static public long[] Sarray() { return ReadLine().Split().Select(long.Parse).ToArray(); }
        static public List<long> Slist() { return ReadLine().Split().Select(long.Parse).ToList(); }

        static readonly long Mod = 1000000000 + 7;
        //写経(https://ferin-tech.hatenablog.com/entry/2019/01/09/101410)
        static void Main(string[] args)
        {
            var NM = Sarray();
            var N = NM[0];
            var M = NM[1];
            var g = new int[N].Select(_ => new List<KeyValuePair<long, long>>()).ToArray();
            for(var i=0;i<M;++i)
            {
                var t = Sarray();
                g[t[1] - 1].Add(new KeyValuePair<long, long>(t[0] - 1, t[2]));
            }
            Func<long, long, long> f = (a, b) => Max(a, b);
            Func<long, long, long> h = (a, b) => a + b;
            LazySegmentTree<long, long> seg = new LazySegmentTree<long, long>((int)N + 2, f, h, h, 0, 0);

            for(var i=0;i<N;++i)
            {
                long now = 0;
                if (i != 0) now = Max(now, seg.query(0, i));
                seg.update(i, i + 1, now);
                foreach (var p in g[i])
                    seg.update((int)p.Key, i + 1, p.Value);
            }
            long ans = Max(0L, seg.query(0, (int)N + 1));
            WriteLine(ans);
        }
        public class LazySegmentTree<Monoid, OperatorMonoid> where OperatorMonoid : IEquatable<OperatorMonoid>
        {
            int sz, height;
            Monoid[] data;
            OperatorMonoid[] lazy;
            readonly Func<Monoid, Monoid, Monoid> f;
            readonly Func<Monoid, OperatorMonoid, Monoid> g;
            readonly Func<OperatorMonoid, OperatorMonoid, OperatorMonoid> h;
            readonly Monoid M1;
            readonly OperatorMonoid OM0;

            public LazySegmentTree(int n,
                Func<Monoid, Monoid, Monoid> f, Func<Monoid, OperatorMonoid, Monoid> g, Func<OperatorMonoid, OperatorMonoid, OperatorMonoid> h,
                Monoid M1, OperatorMonoid OM0
                )
            {
                this.f = f;
                this.g = g;
                this.h = h;
                this.M1 = M1;
                this.OM0 = OM0;
                sz = 1;
                height = 0;
                while (sz < n) { sz <<= 1; ++height; }
                data = new int[sz * 2].Select(_ => M1).ToArray();
                lazy = new int[sz * 2].Select(_ => OM0).ToArray();
            }
            public void set(int k, Monoid x) => data[k + sz] = x;
            public void build()
            {
                for (int k = sz - 1; 0 < k; --k)
                    data[k] = f(data[2 * k + 0], data[2 * k + 1]);
            }
            void propagete(int k)
            {
                if (!lazy[k].Equals(OM0))
                {
                    lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
                    lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
                    data[k] = reflect(k);
                    lazy[k] = OM0;
                }
            }
            Monoid reflect(int k) => lazy[k].Equals(OM0) ? data[k] : g(data[k], lazy[k]);
            void recalc(int k)
            {
                while (0 != (k >>= 1))
                {
                    data[k] = f(reflect(2 * k + 0), reflect(2 * k + 1));
                }
            }
            void thrust(int k)
            {
                for (int i = height; 0 < i; --i)
                    propagete(k >> i);
            }
            public void update(int a, int b, OperatorMonoid x)
            {
                thrust(a += sz);
                thrust(b += sz - 1);
                for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1)
                {
                    if (0 != (l & 1)) { lazy[l] = h(lazy[l], x); ++l; }
                    if (0 != (r & 1)) { --r; lazy[r] = h(lazy[r], x); }
                }
                recalc(a);
                recalc(b);
            }
            public Monoid query(int a, int b)
            {
                thrust(a += sz);
                thrust(b += sz - 1);
                Monoid L = M1, R = M1;
                for (int l = 1, r = b + 1; l < r; l >>= 1, r >>= 1)
                {
                    if (0 != (l & 1)) L = f(L, reflect(l++));
                    if (0 != (r & 1)) R = f(reflect(--r), R);
                }
                return f(L, R);
            }
            public Monoid this[int k] => query(k, k + 1);
        }

    }
}