{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE RankNTypes #-}
import qualified Data.ByteString.Lazy.Char8 as B
import Data.Maybe
import Data.List
import qualified Data.IntSet as IS
import qualified Data.Vector as V
import qualified Data.Vector.Mutable as VM
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import Control.Monad
import Control.Monad.Primitive
import Control.Monad.ST
import Debug.Trace
-- trace _ = id

solve :: Int -> Int -> [(Int,Int,Int)] -> Int
solve bN bM lras = runST $ do
    vec <- VUM.new (4*bN)
    recIntv <- VM.replicate (4*bN) IS.empty
    sgtAct_ mfInit vec bN 0 bN
    forM_ [0..bM-1] $ \i -> do
      let (l,r,a) = vLRA VU.! i
      sgtAct (mfAdd True a recIntv i) vec bN (l-1) r
    lpAct 0 0 vec recIntv
  where

  lpAct !ans !vSum vec recIntv = do
      (vMax, arg) <- sgtAct mfMax vec bN 0 bN
      removed <- sgtAct (mfRemove bN recIntv vLRA) vec bN arg (arg+1)
      if removed == 0 then return ans else
        lpAct (max ans (vSum + vMax)) (vSum + vMax) vec recIntv

      

  vLRA = VU.fromListN bM lras


mfInit SgtIn rc vec node l r = do
  VUM.write vec node (0, 0, l)
  when (l+1 < r) rc
mfInit _ _ _ _ _ _ = error "internal error"
    
mfAdd flag a recIntv i ft rc vec node l r = sub ft >> sgNodeInfo vec node where
  sub SgtIn = do
    VUM.modify vec (\(vSum,p,q) -> (vSum + a,p,q)) node
    if flag then VM.modify recIntv (IS.insert i) node
      else VM.modify recIntv (IS.delete i) node
  sub SgtOut = return ()
  sub SgtOther = do
    (m, ma) <- maxWithArg <$> rc
    VUM.modify vec (\(vSum,_,_) -> (vSum, m, ma)) node
  
mfMax SgtIn rc vec node l r = sgNodeInfo vec node
mfMax SgtOut rc vec node l r = return (minBound :: Int, -1)
mfMax SgtOther rc vec node l r = do
  (m, ma) <- maxWithArg <$> rc
  (vSum,_,_) <- VUM.read vec node
  return (vSum + m, ma)

mfRemove bN recIntv vLRA ft rc vec node l r = case ft of
  SgtIn -> sub
  SgtOut -> return 0
  SgtOther -> liftM2 (\(x,y) z -> x+y+z) rc sub
  where sub = do
          is <- VM.read recIntv node
          let len = IS.size is
          forM_ (IS.toList is) $ \i -> do
            let (l,r,a) = vLRA VU.! i
            sgtAct (mfAdd False (-a) recIntv i) vec bN (l-1) r
          return len

sgNodeInfo vec node = (\(s,m,a) -> (s+m,a)) <$> VUM.read vec node
maxWithArg ((m1,ma1), (m2,ma2)) = if m1 >= m2 then (m1,ma1) else (m2,ma2)

-- segment tree function type
data SgtFT = SgtIn | SgtOut | SgtOther deriving(Show)

sgtAct :: forall m a b. (PrimMonad m, VUM.Unbox a) =>
          (SgtFT -> m (b,b) ->
             VUM.MVector (PrimState m) a -> Int -> Int -> Int -> m b) ->
          VUM.MVector (PrimState m) a ->
          Int ->
          Int ->
          Int ->
          m b
sgtAct mf vec n left right = sub 0 0 n where
  sub :: Int -> Int -> Int -> m b
  sub node l r =
    mf (sgtft left right l r) (sgtChildAct sub node l r) vec node l r

sgtAct_ :: (PrimMonad m, VUM.Unbox a) =>
           (SgtFT -> m () ->
              VUM.MVector (PrimState m) a -> Int -> Int -> Int -> m ()) ->
           VUM.MVector (PrimState m) a ->
           Int ->
           Int ->
           Int ->
           m ()
sgtAct_ mf vec n left right = sub 0 0 n where
  sub node l r =
    mf (sgtft left right l r) (sgtChildAct_ sub node l r) vec node l r

sgtChildAct :: (Monad m) =>
               (Int -> Int -> Int -> m b) -> Int -> Int -> Int -> m (b,b)
sgtChildAct rc' node l r =
  let mid = (l + r) `div` 2
  in (,) <$> rc' (2*node + 1) l mid <*> rc' (2*node + 2) mid r

sgtChildAct_ :: (Monad m) =>
               (Int -> Int -> Int -> m ()) -> Int -> Int -> Int -> m ()
sgtChildAct_ rc' node l r = sgtChildAct rc' node l r >> return ()

sgtft :: Int -> Int -> Int -> Int -> SgtFT
sgtft left right l r
  | left <= l && r <= right = SgtIn
  | r <= left || right <= l = SgtOut
  | otherwise               = SgtOther

traceL :: Show a => String -> a -> b -> b
traceL label showObj val = trace (label ++ " " ++ show showObj) val

traceLM :: (Monad m, Show a) => String -> (b -> a) -> m b -> m b
traceLM label showFn act = do
  aaa <- act
  traceL label (showFn aaa) (return ())
  return aaa

readBInt :: B.ByteString -> Int
readBInt = fst . fromJust . B.readInt

tmain :: B.ByteString -> Int
tmain cont =
  let remLines0 = map B.words (B.lines cont)
      [bs_bN,bs_bM]:remLines1 = remLines0
      bN = readBInt bs_bN
      bM = readBInt bs_bM
      lras = map (\[x1,x2,x3] -> (readBInt x1,readBInt x2,readBInt x3)) remLines1
  in solve bN bM lras

outAnswer :: Int -> IO ()
outAnswer = putStrLn . show

main :: IO ()
main = outAnswer . tmain =<< B.getContents


-------------------------------------------------------------------------------

inp1 = "5 3\n1 3 10\n2 4 -10\n3 5 10\n"
inp2 = "3 4\n1 3 100\n1 1 -10\n2 2 -20\n3 3 -30\n"
inp3 = "1 1\n1 1 -10\n"
inp4 = "1 5\n1 1 1000000000\n1 1 1000000000\n1 1 1000000000\n1 1 1000000000\n1 1 1000000000\n"
inp5 = "6 8\n5 5 3\n1 1 10\n1 6 -8\n3 6 5\n3 4 9\n5 5 -2\n1 3 -6\n4 6 -7\n"
tv1 = tmain $ B.pack inp1
tv2 = tmain $ B.pack inp2
tv3 = tmain $ B.pack inp3
tv4 = tmain $ B.pack inp4
tv5 = tmain $ B.pack inp5
test1 = tv1 == 20
test2 = tv2 == 90
test3 = tv3 == 0
test4 = tv4 == 5000000000
test5 = tv5 == 10
alltest = test1 && test2 && test3 && test4 && test5

