{-# OPTIONS_GHC -O2 -funbox-strict-fields #-}
-- https://qiita.com/drken/items/cce6fc5c579051e64fab#abc-087-d-people-on-a-line の Haskell 実装
import           Control.Monad               (forM_, when)
import           Control.Monad.ST            (ST, runST)
import qualified Data.ByteString.Char8       as BS
import           Data.Maybe                  (fromJust)
import           Data.Vector.Unboxed.Mutable (STVector, Unbox)
import qualified Data.Vector.Unboxed.Mutable as MV

main :: IO ()
main = do
  [n, m] <- readInts <$> BS.getLine
  lrds <- map readInts . BS.lines <$> BS.getContents
  putStrLn $ if solve n m lrds then "Yes" else "No"

solve :: Int -> Int -> [[Int]] -> Bool
solve n _ lrds = runST $ do
  wuf <- create n 0 :: ST s (WeightedUnionFind s Int)
  allM (solve' wuf) lrds

solve' :: WeightedUnionFind s Int -> [Int] -> ST s Bool
solve' wuf [l, r, d] = do
  let (l', r') = (l - 1, r - 1)
  f <- find wuf l' r'
  if f
    then do
      d' <- diff wuf l' r'
      return $ d' == d
    else do
      _ <- unite wuf l' r' d
      return True
solve' _ _ = undefined

allM :: (Monad m) => (a -> m Bool) -> [a] -> m Bool
allM _ []     = return True
allM p (x:xs) = do
  q <- p x
  if q
    then allM p xs
    else return False

readInt :: BS.ByteString -> Int
readInt = fst . fromJust . BS.readInt

readInts :: BS.ByteString -> [Int]
readInts = map readInt . BS.words

-- WeightedUnionFind
data WeightedUnionFind s a = WeightedUnionFind
  { par  :: STVector s Int
  , rank :: STVector s Int
  , dw   :: STVector s a
  }

create :: Unbox a => Int -> a -> ST s (WeightedUnionFind s a)
create n w = do
  par' <- MV.new n
  forM_ [0 .. n-1] $ \i ->
    MV.write par' i i
  rank' <- MV.replicate n 0
  dw' <- MV.replicate n w
  return $ WeightedUnionFind par' rank' dw'

root :: (Num a, Unbox a) => WeightedUnionFind s a -> Int -> ST s Int
root wuf x = do
  px <- MV.read (par wuf) x
  if px == x
    then return x
    else do
      r <- root wuf px
      dwpx <- MV.read (dw wuf) px
      MV.modify (dw wuf) (+ dwpx) x
      MV.write (par wuf) x r
      return r

weight :: (Num a, Unbox a) => WeightedUnionFind s a -> Int -> ST s a
weight wuf x = root wuf x >> MV.read (dw wuf) x

unite :: (Num a, Unbox a) => WeightedUnionFind s a -> Int -> Int -> a -> ST s Bool
unite wuf x y w = do
  wx <- weight wuf x
  wy <- weight wuf y
  let w' = w + wx - wy
  x' <- root wuf x
  y' <- root wuf y
  if x' == y'
    then return False
    else do
      rx <- MV.read (rank wuf) x
      ry <- MV.read (rank wuf) y
      let (x'', y'', w'') = if rx >= ry then (x', y', w') else (y', x', -w')
      when (rx == ry) $ MV.modify (rank wuf) (+ 1) x''
      MV.write (par wuf) y'' x''
      MV.write (dw wuf) y'' w''
      return True

find :: (Num a, Unbox a) => WeightedUnionFind s a -> Int -> Int -> ST s Bool
find wuf x y = (==) <$> root wuf x <*> root wuf y

diff :: (Num a, Unbox a) => WeightedUnionFind s a -> Int -> Int -> ST s a
diff wuf x y = (-) <$> weight wuf y <*> weight wuf x
