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: # coding: UTF-8
  from collections import deque
  
  # testdata
  
  
  class Graph:
      # nodes
      # links
      def __init__(self):
          self.nodes = set()
          self.links = {}
          # nodes -> [tuple(f,cost)]
  
      def readtext(self):
          N, M = map(int, input().split())
          for i in range(M):
              v, w, c = map(int, input().split())
              self.addlink((v, w, c))
  
      def addlink(self, link):
          v, w, c = link
          if v not in self.nodes:
              self.nodes.add(v)
              self.links[v] = []
          if w not in self.nodes:
              self.nodes.add(w)
              self.links[w] = []
  
          if v in self.links:
              self.links[v].append((w, c))
              self.links[w].append((v, -c))
          else:
              self.links[v] = []
              self.links[v].append((w, c))
              self.links[w].append((v, -c))
  
      def addlinks(self, links):
          for link in links:
              self.addlink(link)
  
      def depthfirstsearch(self, so):
          visited = set()
          linq = {}
          # O(links)
          for key in self.links:
              linq[key] = deque(self.links[key])
  
          # recursive subfunction
          def dfsrec(v, so):
              so.enter()
              visited.add(v)
              while linq[v]:
                  cand, cost = linq[v].popleft()
                  if cand not in visited:
                      so.beforeEnter(v, cand, cost)
                      so = dfsrec(cand, so)
              so.exit()
              return so
  
          # call subfunction
          noq = deque(self.nodes)
          while noq:
              x = noq.pop()
              if x not in visited:
                  so.enterConnectedPart(x)
                  so = dfsrec(x, so)
          return so
  
  
  class Searcher:
      def __init__(self):
          pass
  
      def enter(self):
          pass
  
      def exit(self):
          pass
  
      def enterConnectedPart(self):
          pass
  
  
  class TimeSearcher(Searcher):
      def __init__(self, graph):
          self.time = 0
          self.parts = 0
  
          self.dist = {}  # nodes -> integer
          for node in graph.nodes:
              self.dist[node] = None
  
      def beforeEnter(self, v, cand, cost):
          self.dist[cand] = self.dist[v] + cost
  
      def enter(self):
          self.time += 1
  
      # def exit(self):
      #  self.time += 1
  
      def enterConnectedPart(self, start):
          self.parts += 1
          self.dist[start] = 0
  
      def show(self):
          for node in self.dist:
              print(str(node) + " at " + str(self.dist[node]))
  
      def validate(self, graph):
          for v in graph.links:
              for w, cost in graph.links[v]:
                  if self.dist[w] != self.dist[v] + cost:
                      return False
          return True
  
  
  if __name__ == "__main__":
      g = Graph()
      g.readtext()
      so = TimeSearcher(g)
      so = g.depthfirstsearch(so)
      if so.validate(g):
          print("Yes")
      else:
          print("No")
  
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"}]