output_description: If there exists a set of values (x_1, x_2, ..., x_N) that is consistent with
  all given pieces of information, print `Yes`; if it does not exist, print
  `No`.
  
  * * *
input_description: Input is given from Standard Input in the following format:
  
      
      
      N M
      L_1 R_1 D_1
      L_2 R_2 D_2
      :
      L_M R_M D_M
attempt: import sys
  import math
  from collections import defaultdict
  
  sys.setrecursionlimit(10**7)
  
  
  def input():
      return sys.stdin.readline()[:-1]
  
  
  mod = 10**9 + 7
  
  
  def I():
      return int(input())
  
  
  def II():
      return map(int, input().split())
  
  
  def III():
      return list(map(int, input().split()))
  
  
  def Line(N, num):
      if num == 1:
          return [I() for _ in range(N)]
      else:
          read_all = [tuple(II()) for _ in range(N)]
          return map(list, zip(*read_all))
  
  
  #################
  
  
  def scc(N, G, RG):
      used = [False] * N
      group = [None] * N
      order = []
  
      def dfs(S):
          i_order = []
          temp_order = []
          level = 0
          while S:
              v1 = S.pop()
              if used[v1[0]]:
                  continue
              if v1[1] < level:
                  for _ in range(len(temp_order) - v1[1]):
                      x = temp_order.pop()
                      i_order.append(x)
                  level = v1[1]
              level += 1
              if not used[v1[0]]:
                  for v1_to in G[v1[0]]:
                      if not used[v1_to]:
                          S.append((v1_to, level))
                  temp_order.append(v1[0])
                  used[v1[0]] = True
          for t in reversed(temp_order):
              i_order.append(t)
          return i_order
  
      for i in range(N):
          if not used[i]:
              i_order = dfs([(i, 0)])
              order += i_order
  
      def rdfs(S, col):
          used[S[0]] = True
          while S:
              v1 = S.pop()
              for v1_to in RG[v1]:
                  if not used[v1_to]:
                      used[v1_to] = True
                      S.append(v1_to)
              group[v1] = col
  
      used = [False] * N
      label = 0
      for s in reversed(order):
          if not used[s]:
              rdfs([s], label)
              label += 1
      return label, group
  
  
  def edges_to_pt(s, t, n, directed=False):
      pt = [[] for _ in range(n)]
      for i in range(len(s)):
          pt[s[i] - 1].append(t[i] - 1)
          if directed == False:
              pt[t[i] - 1].append(s[i] - 1)
      return pt
  
  
  N, M = II()
  if M > 0:
      L, R, D = Line(M, 3)
  else:
      print("Yes")
      exit()
  
  pt = edges_to_pt(L, R, N)
  label, group = scc(N, pt, pt)
  
  x = []
  used = [False] * label
  for i in range(N):
      if not used[group[i]]:
          x.append(i)
          used[group[i]] = True
  
  pt_l = [[] for _ in range(N)]
  for i in range(M):
      pt_l[L[i] - 1].append((R[i] - 1, D[i]))
      pt_l[R[i] - 1].append((L[i] - 1, -D[i]))
  
  check_visited = [False] * N
  l = [None] * N
  for v in x:
      check_visited[v] = True
      l[v] = 0
      S = [v]
      while S:
          v1 = S.pop()
          for i in pt_l[v1]:
              if check_visited[i[0]] == False:
                  check_visited[i[0]] = True
                  l[i[0]] = l[v1] + i[1]
                  S.append(i[0])
              else:
                  if l[i[0]] == l[v1] + i[1]:
                      continue
                  else:
                      print("No")
                      exit()
  
  print("Yes")
  
problem_description: Statement
  
  There are N people standing on the x-axis. Let the coordinate of Person i be
  x_i. For every i, x_i is an integer between 0 and 10^9 (inclusive). It is
  possible that more than one person is standing at the same coordinate.
  
  You will given M pieces of information regarding the positions of these
  people. The i-th piece of information has the form (L_i, R_i, D_i). This means
  that Person R_i is to the right of Person L_i by D_i units of distance, that
  is, x_{R_i} - x_{L_i} = D_i holds.
  
  It turns out that some of these M pieces of information may be incorrect.
  Determine if there exists a set of values (x_1, x_2, ..., x_N) that is
  consistent with the given pieces of information.
samples: [{"input": "3 3\n    1 2 1\n    2 3 1\n    1 3 2", "output": "Yes\n    \n\nSome possible sets of values (x_1, x_2, x_3) are (0, 1, 2) and (101, 102,\n103).\n\n* * *"}, {"input": "3 3\n    1 2 1\n    2 3 1\n    1 3 5", "output": "No\n    \n\nIf the first two pieces of information are correct, x_3 - x_1 = 2 holds, which\nis contradictory to the last piece of information.\n\n* * *"}, {"input": "4 3\n    2 1 1\n    2 3 5\n    3 4 2", "output": "Yes\n    \n\n* * *"}, {"input": "10 3\n    8 7 100\n    7 9 100\n    9 8 100", "output": "No\n    \n\n* * *"}, {"input": "100 0", "output": "Yes"}]