import java.io.{BufferedReader, InputStream, InputStreamReader}
import java.util.StringTokenizer

import scala.collection.mutable
import scala.util.Sorting
import math.{abs, max, min}
import scala.collection.mutable.ArrayBuffer

object Main {
  val MOD = 1000000007
  def solve(): Unit = {
    val sc = new InputReader(System.in)
    val N = sc.nextInt()
    val M = sc.nextInt()

    type Node = Int
    type Edge = (Node, Int)
    val E = Array.fill[ArrayBuffer[Edge]](N)(ArrayBuffer.empty)
    (0 until M) foreach { _ =>
      val l = sc.nextInt() - 1
      val r = sc.nextInt() - 1
      val d = sc.nextInt()
      E(l) += ((r, d))
      E(r) += ((l, -d))
    }

    val INF = 1000000010
    val d = Array.fill[Int](N)(INF)

    (0 until N) foreach { i =>
      if (d(i) == INF) {
        dfs(i, 0)
      }
    }

    def dfs(v: Node, cost0: Int): Unit = {
      d(v) = cost0
      E(v) foreach { case (u, cost) =>
        if (d(u) == INF) dfs(u, cost0 + cost)
      }
    }

    var valid = true
    (0 until N) foreach { v =>
      E(v) foreach { case (u, cost) =>
        valid &= d(v) + cost == d(u)
      }
    }

    if (valid) println("Yes") else println("No")
  }


  def main(args: Array[String]): Unit = {
    solve()
  }


  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = null

    def next: String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next.toInt
    def nextLong(): Long = next.toLong
    def nextChar(): Char = next.charAt(0)
  }

}
