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.

-----Constraints-----
 - 1 \leq N \leq 100 000
 - 0 \leq M \leq 200 000
 - 1 \leq L_i, R_i \leq N (1 \leq i \leq M)
 - 0 \leq D_i \leq 10 000 (1 \leq i \leq M)
 - L_i \neq R_i (1 \leq i \leq M)
 - If i \neq j, then (L_i, R_i) \neq (L_j, R_j) and (L_i, R_i) \neq (R_j, L_j).
 - D_i are integers.

-----Input-----
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

-----Output-----
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.

-----Sample Input-----
3 3
1 2 1
2 3 1
1 3 2

-----Sample Output-----
Yes

Some possible sets of values (x_1, x_2, x_3) are (0, 1, 2) and (101, 102, 103).

Difficulty: interview

Starter code:

Solutions:
import sys
import math
import collections
import bisect
import itertools

# import numpy as np

sys.setrecursionlimit(10 ** 7)
INF = 10 ** 16
MOD = 10 ** 9 + 7
# MOD = 998244353

ni = lambda: int(sys.stdin.readline().rstrip())
ns = lambda: list(map(int, sys.stdin.readline().rstrip().split()))
na = lambda: list(map(int, sys.stdin.readline().rstrip().split()))
na1 = lambda: list([int(x) - 1 for x in sys.stdin.readline().rstrip().split()])


# ===CODE===

def main():
    n, m = ns()
    e = [[] for _ in range(n)]
    for _ in range(m):
        l, r, d = ns()
        l, r = l - 1, r - 1
        e[l].append([r, d])
        e[r].append([l, -d])

    visited = [False] * n
    dist_mat = [INF] * n

    for i in range(n):
        if visited[i]:
            continue
        que = collections.deque()
        que.append([i, 0])
        visited[i] = True
        dist_mat[i] = 0
        while que:
            idx, dist = que.popleft()
            for ei, di in e[idx]:
                if visited[ei]:
                    if dist + di == dist_mat[ei]:
                        continue
                    else:
                        print("No")
                        return
                else:
                    visited[ei] = True
                    dist_mat[ei] = dist + di
                    que.append([ei, dist + di])

    print("Yes")


def __starting_point():
    main()

__starting_point()

import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.ranks=[0]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return self.dist[x],x
        else:
            tmp=self.find(self.parents[x])
            self.dist[x]+=tmp[0]
            self.parents[x]=tmp[1]
            return self.dist[x],self.parents[x]
    
    def union(self,x,y,d):
        rx=self.find(x)[-1]
        ry=self.find(y)[-1]
        diff=d+self.dist[x]-self.dist[y]
        if rx==ry:
            if diff!=0:
                return True
            return False
        if self.ranks[ry]>self.ranks[rx]:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=rx
        self.dist[ry]=diff
        if self.ranks[ry]==self.ranks[rx]:
            self.ranks[rx]+=1
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        print('Yes')
def __starting_point():
    main()

__starting_point()

from collections import deque


n, m = map(int, input().split())
rels = [None] + [[] for _ in range(n)]
for _ in range(m):
    l, r, d = map(int, input().split())
    rels[l].append((r, d))
    rels[r].append((l, -d))

x = [None] + [None] * n
i = 0
while i < n:
    i += 1
    if x[i] is not None:
        continue

    q = deque()
    x[i] = 0
    q.append(i)
    while q:
        x1 = q.popleft()
        for x2, d in rels[x1]:
            if x[x1] is not None and x[x2] is not None:
                if x[x2] - x[x1] != d:
                    print('No')
                    return
                continue
            if x[x1] is not None and x[x2] is None:
                x[x2] = x[x1] + d
                q.append(x2)
            elif x[x1] is None and x[x2] is not None:
                x[x1] = x[x2] - d
                q.append(x1)

print('Yes')

from collections import deque
N, M = map(int, input().split())
G = [[] for _ in range(N)]
for i in range(M):
    l, r, d = map(int, input().split())
    l -= 1
    r -= 1
    G[l].append([r, d])
    G[r].append([l, -d])
INF = float('inf')
dist = [INF]*N
seen = [False]*N
q = deque([])
for s in range(N):
    if dist[s] != INF:
        continue
    q.append([s,0])
    while len(q) != 0:
        p = q.popleft()
        if seen[p[0]] and dist[p[0]] != p[1]:
            print('No')
            return
        elif seen[p[0]] and dist[p[0]] == p[1]:
            continue
        else:
            dist[p[0]] = p[1]
            seen[p[0]] = True
            for np in G[p[0]]:
                q.append([np[0], p[1] + np[1]])
print('Yes')

import sys
sys.setrecursionlimit(10**7)

def main():
    N, M = list(map(int, input().split()))
    C = [[] for _ in range(N)]
    for _ in range(M):
        l, r, d = list(map(int, input().split()))
        C[l - 1].append((r - 1, d))
        C[r - 1].append((l - 1, -d))
    INF = 10 ** 10
    P = [INF] * N
    def dfs(n, p, f):
        if P[n] != INF:
            if P[n] != p:
                return False
            return True
        P[n] = p
        for i, d in C[n]:
            if i == f:
                continue
            if not dfs(i, p + d, n):
                return False
        return True
            
    for i in range(N):
        if P[i] != INF:
            continue
        if not dfs(i, 0, -1):
            return False
    return True

print(('Yes' if main() else 'No'))


import sys
readline = sys.stdin.readline

class WeightedUnionFind:
    def __init__(self, n):
        self.parents = [i for i in range(n)]
        self.rank = [0] * n
        # 根への距離を管理
        self.weight = [0] * n

    def find(self, x):
        if self.parents[x] == x:
            return x
        else:
            y = self.find(self.parents[x])
            # 親への重みを追加しながら根まで走査
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = y
            return y

    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.parents[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ yの木の高さ
        else:
            self.parents[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            # 木の高さが同じだった場合の処理
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)

    # xからyへのコスト
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]

def main():
    N, M = map(int, readline().rstrip().split())    
    uf = WeightedUnionFind(N)

    for _ in range(M):
        l, r, d = map(int, readline().rstrip().split())
        l -= 1
        r -= 1
        if uf.same(l, r):
            if uf.diff(l, r) != d:
                print('No')
                return

        uf.union(l, r, d)
    
    print('Yes')

def __starting_point():
    main()
__starting_point()

import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return self.dist[x],x
        else:
            tmp=self.find(self.parents[x])
            self.dist[x]+=tmp[0]
            self.parents[x]=tmp[1]
        return self.dist[x], self.parents[x]
    
    def union(self,x,y,d):
        rx=self.find(x)[1]
        ry=self.find(y)[1]
        diff=self.dist[y]-self.dist[x]-d
        if rx==ry:
            if diff!=0:
                return True
            return False
        if diff<0:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
        self.parents[rx]=ry
        self.dist[rx]=diff
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        if max(-d-1 for d in v.parents if d<0) >10**9:
            print('No')
        else:
            print('Yes')
def __starting_point():
    main()

__starting_point()

# Union Find 木
from sys import setrecursionlimit


def find(parent, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, t)
    parent[i] = t
    return t


def pos(x, i):
    j, k = x[i]
    if i == j:
        return i, 0
    l, m = pos(x, j)
    x[i] = (l, m + k)
    return x[i]


setrecursionlimit(10 ** 6)

N, M = list(map(int, input().split()))
LRD = [tuple(map(int, input().split())) for _ in range(M)]

parent = [-1] * (N + 1)
x = [(i, 0) for i in range(N + 1)]
for L, R, D in LRD:
    i = find(parent, L)
    j = find(parent, R)
    if i != j:
        x[j] = (i, D - pos(x, R)[1] + pos(x, L)[1])
        parent[i] += parent[j]
        parent[j] = i
    else:
        if pos(x, L)[1] + D != pos(x, R)[1]:
            print('No')
            return
print('Yes')


visited=set()
success=1
import sys
sys.setrecursionlimit(1000000)
def dfs(graph, node):
  nonlocal visited
  nonlocal b
  nonlocal success
  if node not in visited:
    visited.add(node)
    for counter in range(len(graph[node-1][0])):
      if b[graph[node-1][0][counter]-1]==10000000000000000000:
        b[graph[node-1][0][counter]-1]=b[node-1]+graph[node-1][1][counter]
      else:
        if  b[graph[node-1][0][counter]-1]!=b[node-1]+graph[node-1][1][counter]:
          success=0
      dfs(graph, graph[node-1][0][counter])
      
n,m=map(int,input().split())
a=[]
b=[10000000000000000000]*n
for i in range(n):
  a.append([[],[]])
done=[0]*n
for i in range(m):
  l,r,d=map(int,input().split())
  a[l-1][0].append(r)
  a[l-1][1].append(d)
  a[r-1][0].append(l)
  a[r-1][1].append(-d)
current=[1]
for i in range(n):
  if i+1 in visited:
    continue
  b[i]=0
  dfs(a,i+1)
if success==0:
  print('No')
else:
  print('Yes')

import sys
from collections import deque
input = sys.stdin.readline

def main():
  n, m = map(int, input().split())
  tree = [[] for _ in range(n)]
  for i in range(m):
    l, r, d = map(int, input().split())
    tree[l-1].append((r-1, d))
    tree[r-1].append((l-1, -d))
  
  ans = [0]*n
  not_yet = deque([])
  already = [False]*n
  judge = True
  
  for i in range(n):
    if already[i]:
      continue
    already[i] = True
    for v in tree[i]:
      index, dist = v[0], v[1]
      ans[index] = dist
      already[index] = True
      not_yet.append(index)
    while not_yet:
      index = not_yet.popleft()
      for v in tree[index]:
        index2, dist = v[0], v[1]
        if already[index2]:
          if ans[index] + dist != ans[index2]:
            judge = False
        else:
          already[index2] = True
          ans[index2] = ans[index] + dist
          not_yet.append(index2)
          
  print("Yes" if judge else "No")
  
def __starting_point():
  main()
__starting_point()

n,m=map(int,input().split())
lrd=[list(map(int,input().split())) for _ in range(m)]
g=[[] for _ in range(n)]
for l,r,d in lrd:
  g[l-1].append([d,r-1])
  g[r-1].append([-d,l-1])

no_seen=set(range(n))
inf=float('inf')
dst=[inf]*n
while no_seen:
  todo=[[0,no_seen.pop()]]
  #print(todo)
  while todo:
    d,t=todo.pop()
    no_seen.discard(t)
    l=g[t]
    for di,ti in l:
      if dst[ti]!=inf and dst[ti]!=d+di:
        print('No')
        return
      elif dst[ti]!=inf and dst[ti]==d+di:
        pass
      else:
        todo.append([d+di,ti])
        dst[ti]=d+di

print('Yes')

import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return self.dist[x],x
        else:
            tmp=self.find(self.parents[x])
            self.dist[x]+=tmp[0]
            self.parents[x]=tmp[1]
        return self.dist[x], self.parents[x]
    
    def union(self,x,y,d):
        _,rx=self.find(x)
        _,ry=self.find(y)
        diff=self.dist[y]-self.dist[x]-d
        if rx==ry:
            if diff!=0:
                return True
            return False
        if diff<0:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
        self.parents[rx]=ry
        self.dist[rx]=diff
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        if max(-d-1 for d in v.parents if d<0) >10**9:
            print('No')
        else:
            print('Yes')
def __starting_point():
    main()

__starting_point()

from collections import deque
n, m = list(map(int, input().split()))
g = [[] for _ in range(n + 1)]
q = deque([])
visited = set()
dist = [None] * (n + 1)

for i in range(m):
    a, b, k = list(map(int, input().split()))
    g[a].append((b, k))
    g[b].append((a, -k))

def dfs(u):
    q.append(u)
    while q:
        v = q.pop()
        visited.add(v)
        for x, d in g[v]:
            if x not in visited:
                if dist[x] is None:
                    dist[x] = dist[v] + d
                elif dist[x] != dist[v] + d:
                    return False
                q.append(x)
    return True

for i in range(1, n + 1):
    if i not in visited:
        dist[i] = 1
        if not dfs(i):
            print("No")
            return
print("Yes")


import sys
n,m=map(int,input().split())
par=[-1]*n
wei=[0]*n

#重み付きUnion-Find

#xの根を求める
def find(x):
    if par[x] < 0:
        return x
    else:
        px = find(par[x])
        wei[x] += wei[par[x]]
        par[x] = px
        return px

#xの根から距離
def weight(x):
    find(x)
    return wei[x]

#w[y]=w[x]+wとなるようにxとyを併合
def unite(x,y,w):
    w += wei[x]-wei[y]
    x = find(x)
    y = find(y)
    
    if x == y:
        return False
    else:
        #sizeの大きいほうがx
        if par[x] > par[y]:
            x,y = y,x
            w = -w
        par[x] += par[y]
        par[y] = x
        wei[y] = w
        return True

#xとyが同じ集合に属するかの判定
def same(x,y):
    return find(x) == find(y)

#xが属する集合の個数
def size(x):
    return -par[find(x)]

#x,yが同じ集合に属するときのwei[y]-wei[x]
def diff(x,y):
    return weight(y)-weight(x)


for i in range(m):
    l,r,d=map(int,input().split())
    if same(l-1,r-1):
        if d!=diff(l-1,r-1):
            print('No')
            return
    else:
        unite(l-1,r-1,d)

print('Yes')

import sys
readline = sys.stdin.readline

class WeightedUnionFind:
    def __init__(self, n):
        self.parents = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        # 根への距離を管理
        self.weight = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.parents[x] == x:
            return x
        else:
            y = self.find(self.parents[x])
            # 親への重みを追加しながら根まで走査
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = y
            return y

    # 併合
    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.parents[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ yの木の高さ
        else:
            self.parents[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            # 木の高さが同じだった場合の処理
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    # 同じ集合に属するか
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # xからyへのコスト
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]

def main():
    N, M = map(int, readline().rstrip().split())    
    uf = WeightedUnionFind(N)

    for _ in range(M):
        l, r, d = map(int, readline().rstrip().split())
        l -= 1
        r -= 1
        if uf.same(l, r):
            if uf.diff(l, r) != d:
                print('No')
                return

        uf.union(l, r, d)
    
    print('Yes')

def __starting_point():
    main()
__starting_point()

from collections import deque

n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for i in range(m):
    l, r, d = map(int, input().split())
    l -= 1
    r -= 1
    graph[r].append((l, r, -d))
    graph[l].append((r, l, d))

max_int = 10 ** 10
point = [None for _ in range(n)]

for v in range(n):
    Q = deque()
    if point[v] is not None:
        continue
    Q.extend(graph[v])
    while Q:
        next_v, v, d = Q.popleft()
        if point[v] is None:
            point[v] = 0
        if point[next_v] is not None:
            if point[next_v] != point[v] + d:
                print('No')
                return
            else:
                continue
        point[next_v] = point[v] + d
        Q.extend(graph[next_v])
print('Yes')

# 人を頂点と見なしたグラフを作る。有向で、逆向きの場合は正負を反転させて辺を張る
# 頂点からの距離を記録し、一致しない箇所があればNG。
# 全ての辺を通るまで続ける。
# 辺の情報を[{0から行ける頂点},{1から行ける頂点},...]で管理する
# 親には進まないようにしてDFSする

N,M = list(map(int,input().split()))
E = [[] for i in range(N)]
for i in range(M):
  L,R,D = list(map(int,input().split()))
  E[L-1].append([R-1,D])
  E[R-1].append([L-1,-D])
from collections import deque
# 頂点、親、距離
INF = 10 ** 10
dist = [INF] * N
for i in range(N):
  if dist[i] != INF:
    continue
  dist[i] = 0
  q = deque()
  q.append(i)
  while q:
    v = q.popleft()
    for child in E[v]:
      if dist[child[0]] == INF:
        dist[child[0]] = dist[v] + child[1]
        q.append(child[0])
      else:
        if dist[child[0]] != dist[v] + child[1]:
          print("No")
          return
else:
  print("Yes")


import sys
readline = sys.stdin.readline
sys.setrecursionlimit(10**8)
mod = 10**9+7
#mod = 998244353
INF = 10**9
eps = 10**-7

N,M = list(map(int,input().split()))
# 1-indexed union-find
# parent(親)
par = [i for i in range(N+1)]
# rank(深さ)
rank = [0]*(N+1)
# 同グループの頂点数
# size = [1]*(N+1)

# 木の根を求める
def root(x):
    if par[x] == x:             # 根の時
        return x
    else:
        par[x] = root(par[x])   # 経路圧縮
        return par[x]

# xとyの属する集合を併合(ランク有)
def unite(x,y):
    x = root(x)
    y = root(y)
    if x == y:
        return
    if rank[x] < rank[y]:
        par[x] = y              # xの親をyに
        #size[y] += size[x]      # yの頂点数+=xの頂点数
    else:
        par[y] = x              # yの親をxに
        #size[x] += size[y]      # xの頂点数+=yの頂点数
        if rank[x] == rank[y]:
            rank[x] += 1

LRD = [tuple(map(int,readline().split())) for i in range(M)]

for (L,R,D) in LRD:
    unite(L,R)

from collections import defaultdict,deque
rel = defaultdict(lambda: [])

for (L,R,D) in LRD:
    rel[root(L)].append((L,R,D))

for k,v in list(rel.items()):
    dist = defaultdict(lambda: [])
    for (L,R,D) in v:
        dist[L].append((R,D))
        dist[R].append((L,-D))
    que = deque([])
    x = {}
    for k1,v1 in list(dist.items()):
        x[k1] = 0
        for (to,dis) in v1:
            x[to] = dis
            que.append(to)
        break
    while que:
        fro = que.popleft()
        for (to,dis) in dist[fro]:
            if to not in list(x.keys()):
                x[to] = x[fro] + dis
                que.append(to)
    for (L,R,D) in v:
        if x[R] - x[L] != D:
            print('No')
            return
print('Yes')


def main():
    import sys
    input = sys.stdin.readline
    #重み付きUnion-Find

    #xの根を求める
    def find(x):
        if par[x] < 0:
            return x
        else:
            px = find(par[x])
            wei[x] += wei[par[x]]
            par[x] = px
            return px

    #xの根から距離
    def weight(x):
        find(x)
        return wei[x]


    #w[y]=w[x]+wとなるようにxとyを併合
    def unite(x,y,w):
        w += wei[x]-wei[y]
        x = find(x)
        y = find(y)
        
        if x == y:
            return False
        else:
            #sizeの大きいほうがx
            if par[x] > par[y]:
                x,y = y,x
                w = -w
            par[x] += par[y]
            par[y] = x
            wei[y] = w
            return True

    #xとyが同じ集合に属するかの判定
    def same(x,y):
        return find(x) == find(y)

    #xが属する集合の個数
    def size(x):
        return -par[find(x)]

    #x,yが同じ集合に属するときのwei[y]-wei[x]
    def diff(x,y):
        return weight(y)-weight(x)

    n,m = map(int,input().split())

    #初期化
    #par:根なら-size,子なら親の頂点
    #wei:親からの距離,根なら0
    par = [-1]*n
    wei = [0]*n

    for i in range(m):
        l,r,d = map(int,input().split())
        l,r = l-1,r-1
        if same(l,r):
            if d != diff(l,r):
                print('No')
                return
        else:
            unite(l,r,d)
    print('Yes')
            
def __starting_point():
    main()
__starting_point()

def main():
    from collections import deque
    import sys
    input = sys.stdin.readline

    N, M = list(map(int, input().split()))

    g = tuple(set() for _ in range(N))
    h = [0] * N  # 入り次数
    for _ in range(M):
        L, R, D = list(map(int, input().split()))
        L -= 1
        R -= 1
        g[L].add((R, D))
        h[R] += 1

    dist = [-1] * N

    def dfs(s):
        dist[s] = 0
        dq = deque([s])
        while dq:
            v = dq.popleft()
            for u, d in g[v]:
                if ~dist[u]:
                    if dist[u] != dist[v] + d:
                        return False
                else:
                    dist[u] = dist[v] + d
                    dq.append(u)
        return True

    # 始点からのパスを処理
    for s in range(N):
        if h[s]: continue  # sに入ってくるパスがあるので、sを始点にしない
        # if ~dist[s]: continue
        if not dfs(s):
            print('No')
            return

    # サイクルを処理（どの点も入るパスがあり、処理できていない）
    for s in range(N):
        if ~dist[s]: continue
        if not dfs(s):
            print('No')
            return

    print('Yes')


def __starting_point():
    main()

__starting_point()

class unionFind:
    parent = []

    def __init__(self, N):
        self.parent = [i for i in range(N)]
        self.weight = [0]*N

    def root(self, x):
        if self.parent[x] == x:
            return(x)
        else:
            p = self.root(self.parent[x])
            self.weight[x] += self.weight[self.parent[x]]
            self.parent[x] = p
            return(self.parent[x])

    def same(self, x, y):
        x, y = x-1, y-1
        return(self.root(x) == self.root(y))

    def unite(self, x, y, w):
        w -= self.getWeight(x)
        w += self.getWeight(y)
        x, y = x-1, y-1
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return
        else:
            self.parent[x] = y
            self.weight[x] = self.weight[y]+w
            return

    def getWeight(self, x):
        x -= 1
        self.root(x)
        return(self.weight[x])


def main():
    import sys
    input = sys.stdin.readline

    N, M = list(map(int, input().split()))
    G = unionFind(N)
    for i in range(M):
        L, R, D = list(map(int, input().split()))
        if G.same(L, R):
            x = G.getWeight(L)
            y = G.getWeight(R)
            if x == y + D:
                continue
            else:
                print("No")
                return
        else:
            G.unite(L, R, D)
    print("Yes")


main()


# 解説みたよ
import sys
sys.setrecursionlimit(10000000)
input = sys.stdin.readline
n, m = list(map(int, input().split()))
es = [[] for i in range(n)]
l, r, d = [0] * m, [0] * m, [0] * m
for i in range(m):
    l[i], r[i], d[i] = list(map(int, input().split()))
    l[i] -= 1
    r[i] -= 1
    es[l[i]].append((r[i], d[i]))
    es[r[i]].append((l[i], -d[i]))
INF = 1000000000000
value = [INF] * n


def dfs(v):
    for i, di in es[v]:
        if value[i] == INF:
            value[i] = value[v] + di
            dfs(i)


for i in range(n):
    if value[i] == INF:
        value[i] = 0
        dfs(i)

for i, j, k in zip(l, r, d):
    if value[j] - value[i] != k:
        print("No")
        return
print("Yes")


# https://at274.hatenablog.com/entry/2018/02/03/140504
class WeightedUnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        # 根への距離を管理
        self.weight = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            # 親への重みを追加しながら根まで走査
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y

    # 併合
    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ yの木の高さ
        else:
            self.par[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            # 木の高さが同じだった場合の処理
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    # 同じ集合に属するか
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # xからyへのコスト
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]

N,M=map(int,input().split())
uf = WeightedUnionFind(N+1)
for i in range(M):
  l,r,d=map(int,input().split())
  if l>r:
    l,r=r,l
    d=-d
  if uf.same(l,r) and d != uf.diff(l,r):
    print('No')
    return
  uf.union(l,r,d)
print('Yes')

import sys
readline = sys.stdin.readline

class WeightedUnionFind:
    def __init__(self, n):
        self.parents = [i for i in range(n)]
        self.rank = [0] * n
        # 根への距離を管理
        self.weight = [0] * n

    def find(self, x):
        if self.parents[x] == x:
            return x
        else:
            y = self.find(self.parents[x])
            # 親への重みを追加しながら根まで走査
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = y
            #self.parents[x] = self.find(self.parents[x])
            return y
            #return self.parents[x]

    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.parents[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ yの木の高さ
        else:
            self.parents[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            # 木の高さが同じだった場合の処理
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)

    # xからyへのコスト
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]

def main():
    N, M = map(int, readline().rstrip().split())    
    uf = WeightedUnionFind(N)

    for _ in range(M):
        l, r, d = map(int, readline().rstrip().split())
        l -= 1
        r -= 1
        if uf.same(l, r):
            if uf.diff(l, r) != d:
                print('No')
                return

        uf.union(l, r, d)
    
    print('Yes')

def __starting_point():
    main()
__starting_point()

import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return x,self.dist[x]
        else:
            tmp=self.find(self.parents[x])
            self.parents[x]=tmp[0]
            self.dist[x]+=tmp[1]
            return self.parents[x],self.dist[x]
    
    def union(self,x,y,d):
        rx,_=self.find(x)
        ry,_=self.find(y)
        diff=self.dist[y]-self.dist[x]-d
        if rx==ry:
            if diff!=0:
                return True
            return False
        if diff<0:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
        self.parents[rx]=ry
        self.dist[rx]=diff
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        print('Yes')
def __starting_point():
    main()

__starting_point()

import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return self.dist[x],x
        else:
            tmp=self.find(self.parents[x])
            self.dist[x]+=tmp[0]
            self.parents[x]=tmp[1]
            return self.dist[x], self.parents[x]
    
    def union(self,x,y,d):
        rx=self.find(x)[1]
        ry=self.find(y)[1]
        diff=self.dist[y]-self.dist[x]-d
        if rx==ry:
            if diff!=0:
                return True
            return False
        if diff<0:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
        self.parents[rx]=ry
        self.dist[rx]=diff
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        print('Yes')
def __starting_point():
    main()

__starting_point()

n, m = list(map(int, input().split()))
vertices = {i: [] for i in range(n)}
for _ in range(m):
    l, r, d = list(map(int, input().split()))
    vertices[l - 1].append((r - 1, d))
    vertices[r - 1].append((l - 1, -d))


def answer():
    x = [None] * n

    for i in range(n):
        if x[i] is not None:
            continue
        x[i] = 0
        queue = [i]

        while queue:
            i0 = queue.pop()
            for i1, d in vertices[i0]:
                # print(i0, i1, x[i0], x[i1], d)
                if x[i1] is None:
                    x[i1] = x[i0] + d
                    queue.append(i1)
                elif x[i1] != x[i0] + d:
                    return False

    return True


if answer():
    print('Yes')
else:
    print('No')





import sys
from collections import deque

N, M = map(int, sys.stdin.readline().split())

edges = [[] for _ in range(N)]
for _ in range(M):
    l, r, d = map(int, sys.stdin.readline().split())
    edges[l-1].append((r-1, d))
    edges[r-1].append((l-1, -d))

visited = {}
# その人へのパスが複数あり、距離が異なる場合は矛盾
for i in range(N):
    if i in visited:
        continue

    # 連結グラフごとに相対的な距離を決定
    # dist = [0 for _ in range(N)]
    q = deque([(i, 0)])
    while q:
        l, c = q.popleft()
        if l in visited:
            if visited[l] != c:
                print("No")
                return
            continue
        
        visited[l] = c
        # dist[l] = c

        for r, nd in edges[l]:
            q.append((r, c+nd))
    # print(dist)

print("Yes")

# bfs?

def main():
    from collections import deque
    import sys
    input = sys.stdin.readline

    N, M = list(map(int, input().split()))

    g = tuple(set() for _ in range(N))
    h = [0] * N  # 入り次数
    for _ in range(M):
        L, R, D = list(map(int, input().split()))
        L -= 1
        R -= 1
        g[L].add((R, D))
        h[R] += 1

    dist = [-1] * N

    def bfs(s):
        dist[s] = 0
        dq = deque([s])
        while dq:
            v = dq.popleft()
            for u, d in g[v]:
                if ~dist[u]:
                    if dist[u] != dist[v] + d:
                        return False
                else:
                    dist[u] = dist[v] + d
                    dq.append(u)
        return True

    # 始点からのパスを処理
    for s in range(N):
        if h[s]: continue  # sに入ってくるパスがあるので、sを始点にしない
        # if ~dist[s]: continue
        if not bfs(s):
            print('No')
            return

    # サイクルを処理（どの点も入るパスがあり、処理できていない）
    for s in range(N):
        if ~dist[s]: continue
        if not bfs(s):
            print('No')
            return

    print('Yes')


def __starting_point():
    main()

__starting_point()

from heapq import heappop, heappush
N, M = list(map(int, input().split()))
graph = [[] for i in range(N)]
root = [-float("inf")] * N
for i in range(M):
  l, r, d = list(map(int, input().split()))
  graph[l - 1].append([r - 1, d])
  graph[r - 1].append([l - 1, -d])
  
  
for i in range(N):
  if root[i] < -10 ** 10:
    root[i] = 0
    queue = [i]
    while queue:
      now = heappop(queue)
      for j, k in graph[now]:
        if root[j] < - 10 ** 10:
          root[j] = root[now] + k
          heappush(queue, j)
        elif root[j] == root[now] + k:
          continue
        else:
          print("No")
          return
          
print("Yes")


    
    
    
    
    


#float型を許すな
#numpyはpythonで
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)
from collections import Counter, deque
from collections import defaultdict
from itertools import combinations, permutations, accumulate, groupby, product
from bisect import bisect_left,bisect_right
from heapq import heapify, heappop, heappush
from math import floor, ceil,pi,factorial
from operator import itemgetter
def I(): return int(input())
def MI(): return list(map(int, input().split()))
def LI(): return list(map(int, input().split()))
def LI2(): return [int(input()) for i in range(n)]
def MXI(): return [[LI()]for i in range(n)]
def SI(): return input().rstrip()
def printns(x): print(('\n'.join(x)))
def printni(x): print(('\n'.join(list(map(str,x)))))
inf = 10**17
mod = 10**9 + 7

class WeightedUnionfind():
    def __init__(self,n):
        self.par =[i for i in range(n+1)]
        self.rank =[0]*(n+1)
        self.weight =[0]*(n+1)

    def find(self,x):
        if self.par[x]==x:
            return x

        else:
            y =self.find(self.par[x])
            self.weight[x]+=self.weight[self.par[x]]
            self.par[x]=y
            return y

    def union(self,x,y,w):
        rx=self.find(x)
        ry=self.find(y)
        if self.rank[rx]<self.rank[ry]:
            self.par[rx]=ry
            self.weight[rx]=w-self.weight[x]+self.weight[y]
        else:
            self.par[ry]=rx
            self.weight[ry]=-w-self.weight[y]+self.weight[x]
            if self.rank[rx]==self.rank[ry]:
                self.rank[rx]+=1
    def same(self,x,y):
        return self.find(x)==self.find(y)

    def diff(self,x,y):
        return self.weight[x]-self.weight[y]

n,m=MI()
wuf=WeightedUnionfind(n)
for i in range(m):
    l,r,d=MI()
    #print(l,r,d,end=" ")
    #print(wuf.same(l,r))
    if wuf.same(l,r):
        #print(wuf.diff(l,r))
        if wuf.diff(l,r)!=d:
            print("No")
            return
    else:
        wuf.union(l,r,d)
print("Yes")



    
    



    


        


    
    


    

    
            
        
        
    
    
    
    

    
    


    
    

        
        
    




n, m = map(int, input().split())
G = [[] for _ in range(n)]
indeg = [0] * n

for _ in range(m):
    l, r, d = map(int, input().split())
    l -= 1
    r -= 1
    G[l].append((r, d))
    G[r].append((l, -d))

from collections import deque
ng = False
visited = [0] * n
visited_cost = [0] * n

for start in range(n):
    if visited[start]:
        continue
    visited[start] = 1
    st = deque([[start, 0]])
    while st:
        i, cost = st.pop()
        for ni, nd in G[i]:
            if visited[ni] == 0:
                visited[ni] = 1
                visited_cost[ni] = cost + nd
                st.append([ni, cost + nd])
            else:
                # 既に記録されていて、矛盾している場合
                if visited_cost[ni] != cost + nd:
                    # 終了
                    ng = True
                    break
        if ng:
            break
    if ng:
        break
print('No' if ng else 'Yes')

# Union Find 木
from sys import setrecursionlimit, stdin


def find(parent, diff_weight, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, diff_weight, t)
    diff_weight[i] += diff_weight[parent[i]]
    parent[i] = t
    return t


def weight(parent, diff_weight, i):
    find(parent, diff_weight, i)
    return diff_weight[i]


def unite(parent, diff_weight, i, j, d):
    d -= weight(parent, diff_weight, j)
    d += weight(parent, diff_weight, i)
    i = find(parent, diff_weight, i)
    j = find(parent, diff_weight, j)
    if i == j:
        return
    diff_weight[j] = d
    parent[i] += parent[j]
    parent[j] = i


setrecursionlimit(10 ** 6)

N, M = list(map(int, stdin.readline().split()))
LRD = [tuple(map(int, stdin.readline().split())) for _ in range(M)]

parent = [-1] * (N + 1)
diff_weight = [0] * (N + 1)
for L, R, D in LRD:
    i = find(parent, diff_weight, L)
    j = find(parent, diff_weight, R)
    if i != j:
        unite(parent, diff_weight, L, R, D)
    else:
        if weight(parent, diff_weight, L) + D != weight(parent, diff_weight, R):
            print('No')
            return
print('Yes')


import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
    
def main():
    class Unionfind():
        def __init__(self,n):
            self.parents=[-1]*n
            self.dist=[0]*n 
        
        def find(self,x):
            if self.parents[x]<0:
                return self.dist[x],x
            else:
                tmp=self.find(self.parents[x])
                self.dist[x]+=tmp[0]
                self.parents[x]=tmp[1]
            return self.dist[x], self.parents[x]
        
        def union(self,x,y,d):
            rx=self.find(x)[1]
            ry=self.find(y)[1]
            diff=self.dist[y]-self.dist[x]-d
            if rx==ry:
                if diff!=0:
                    return True
                return False
            if diff<0:
                rx,ry=ry,rx
                diff=-diff
            self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
            self.parents[rx]=ry
            self.dist[rx]=diff
            return False
    n,m,*lrd=list(map(int,read().split()))
    edg=[]
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        if max(-d-1 for d in v.parents if d<0) >10**9:
            print('No')
        else:
            print('Yes')
def __starting_point():
    main()

__starting_point()

# Union Find 木
from sys import setrecursionlimit


def find(parent, diff_weight, i):
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, diff_weight, t)
    diff_weight[i] += diff_weight[parent[i]]
    parent[i] = t
    return t


def weight(parent, diff_weight, i):
    find(parent, diff_weight, i)
    return diff_weight[i]


def unite(parent, diff_weight, i, j, d):
    d -= weight(parent, diff_weight, j)
    d += weight(parent, diff_weight, i)
    i = find(parent, diff_weight, i)
    j = find(parent, diff_weight, j)
    if i == j:
        return
    diff_weight[j] = d
    parent[i] += parent[j]
    parent[j] = i


setrecursionlimit(10 ** 6)

N, M = list(map(int, input().split()))
LRD = [tuple(map(int, input().split())) for _ in range(M)]

parent = [-1] * (N + 1)
diff_weight = [0] * (N + 1)
for L, R, D in LRD:
    i = find(parent, diff_weight, L)
    j = find(parent, diff_weight, R)
    if i != j:
        unite(parent, diff_weight, L, R, D)
    else:
        if weight(parent, diff_weight, L) + D != weight(parent, diff_weight, R):
            print('No')
            return
print('Yes')


from collections import deque

N, M = list(map(int, input().split()))

links = [[] for _ in range(N + 1)]
for _ in range(M):
    L, R, D = list(map(int, input().split()))
    links[L].append((R, D))
    links[R].append((L, -D))

t = [None] * (N + 1)
for i in range(1, N + 1):
    if t[i] is not None:
        continue
    t[i] = 0
    s = deque([i])
    while s:
        j = s.popleft()
        for k, l in links[j]:
            if t[k] is None:
                t[k] = t[j] + l
                s.append(k)
            else:
                if t[k] != t[j] + l:
                    print('No')
                    return
print('Yes')


from collections import deque
n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    l, r, d = map(int, input().split())
    graph[l-1].append((r-1, d))
    graph[r-1].append((l-1, -d))
seen = [False]*n
dist = [None]*n
for i in range(n):
    if seen[i]:
        continue
    q = deque([i])
    dist[i] = 0
    while q:
        node = q.popleft()
        if seen[node]:
            continue
        seen[node] = True
        for c_node, d in graph[node]:
            if dist[c_node] is None:
                dist[c_node] = dist[node] + d
            elif dist[c_node] != dist[node] + d:
                print('No')
                return
            q.append(c_node)
print('Yes')

N, M = map(int, input().split())
LRD = [tuple(int(x) for x in input().split()) for _ in range(M)]
Graph = [[] for _ in range(N)]
for l,r,d in LRD:
    Graph[r-1].append((l-1,d))
    Graph[l-1].append((r-1,-d))

seen = set()
Dfr = [0] * N #dist from Root
for root in range(N):
    if root in seen: continue
    seen.add(root)
    V = [root]
    while len(V) != 0: #bfs
        v = V.pop(0)
        for nv,d in Graph[v]:
            if nv in seen and Dfr[nv] != Dfr[v] + d: #bfsで発見済みの値が異なる⇔矛盾
                print('No')
                return
            if nv in seen: continue
            else:
                seen.add(nv)
                Dfr[nv] = Dfr[v] + d
                V.append(nv)
print('Yes')

# potential union findの問題と聞いて
class PotentialUnionFind:
    # あり本実装
    # rankとrootの配列を1つで賄う方法
    def __init__(self, n):
        self.n = n
        self.par = [-1] * n
        self.weight = [0] * n

    # 根を求める
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            px = self.find(self.par[x])
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = px
            return px

    # 頂点からのpotential
    def weight(self, x):
        self.find(x)
        return self.weight[x]

    # 同じかどうかの判定
    def is_same(self, x, y):
        return self.find(x) == self.find(y)

    # 集合の大きさ
    def size(self, x):
        return -self.find(x)

    # 　2つの集合の合体
    # 重みが大きい方に小さい方をつけるようにする
    def unite(self, x, y, w):
        w += self.weight[x] - self.weight[y]
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False

        if self.par[x] > self.par[y]:
            x, y = y, x
            w = -w
        self.par[x] += self.par[y]
        self.par[y] = x
        self.weight[y] = w
        return True

    def diff(self, x, y):
        return self.weight[y] - self.weight[x]


n, m = list(map(int, input().split()))
PUF = PotentialUnionFind(n)
flag = 0
for _ in range(m):
    l, r, d = list(map(int, input().split()))
    l -= 1
    r -= 1
    if PUF.is_same(l, r):
        if abs(PUF.diff(l, r)) == d:
            continue
        else:
            flag = 1
    else:
        PUF.unite(l, r, d)

print(("No" if flag else "Yes"))


def root(x):
    if(par[x]==x):
        return x
    else:
        r=root(par[x])
        diff_weight[x]+=diff_weight[par[x]]
        par[x]=r
        return r

def weight(x):
    root(x)
    return diff_weight[x]

def diff(x,y):
    return weight(y)-weight(x)

def relate(a,b,w):
    w+=weight(a);w-=weight(b)
    a=root(a)
    b=root(b)
    if(a==b):
        return False
    if rank[a]<rank[b]:
        a,b=b,a
        w=-w
    if rank[a]==rank[b]:
        rank[b]+=1
        par[b]=a
    par[b]=a
    diff_weight[b]=w
    siz[a]+=siz[b]
    return True

def size(a):
    return siz[root(a)]
    
def same(a,b):
    return root(a)==root(b)
    
N,M=map(int,input().split())
par=[i for i in range(N)]
siz=[1 for _ in range(N)]
rank=[0 for _ in range(N)]
diff_weight=[0 for _ in range(N)]

for i in range(M):
    L,R,D=map(int,input().split())
    L,R=L-1,R-1
    if same(L,R) and diff(L,R)!=D:
        print('No')
        return
    else:
        relate(L,R,D)
print('Yes')

import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return self.dist[x],x
        else:
            tmp=self.find(self.parents[x])
            self.dist[x]+=tmp[0]
            self.parents[x]=tmp[1]
        return self.dist[x], self.parents[x]
    
    def union(self,x,y,d):
        rx=self.find(x)[1]
        ry=self.find(y)[1]
        diff=self.dist[y]-self.dist[x]-d
        if rx==ry:
            if diff!=0:
                return True
            return False
        if diff<0:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
        self.parents[rx]=ry
        self.dist[rx]=diff
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        if max(-d-1 for d in v.parents if d<0) >10**9:
            print('No')
        else:
            print('Yes')
def __starting_point():
    main()

__starting_point()

n, m = list(map(int, input().split()))
info = [list(map(int, input().split())) for i in range(m)] 

# 重要な事実としてNの最大値×D_iの最大値はちょうど10^4*10^5 = 10^9 = 座標の幅。
# 「位置関係は全て正しく置けるが、0〜10^9に収まらないのでダメ」という可能性は考慮しなくて良い。
# 辺を通って到達可能か否かで分かれる。→幅優先か深さ優先かUnion-Findだな。
# 迷ったら幅優先で書こう。
# なおエッジを1本ずつ（入力された順に）処理するのはマズい。100個の点からなる塊が2つあって、最後にそれが2つの線で結ばれた場合、無矛盾かどうかどうやって判別するか?

from collections import deque

nei = [[] for _ in range(n)]
for edge in info:
    v0 = edge[0] - 1
    v1 = edge[1] - 1
    nei[v0].append((v1, edge[2]))
    nei[v1].append((v0, -edge[2]))

queue = deque()
visited = [False] * n
pos = [None] * n

for i in range(n):
    if visited[i]:
        continue
    queue.append(i)

    pos[i] = 0  # 相対位置なので、値は何でも良い

    while len(queue) > 0:
        v = queue.popleft()
        visited[v] = True

        for n, diff in nei[v]:
            if pos[n] == None:
                pos[n] = pos[v] + diff
                queue.append(n)

            else:
                # 既に訪問済み→座標が決まっている→整合性チェック
                if pos[n] != pos[v] + diff:
                    print('No')
                    return

print('Yes')


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 9)
MOD = 10 ** 9 + 7

N, M = map(int, input().split())

G = [[] for _ in range(N + 1)]
for _ in range(M):
    L, R, D = map(int, input().split())
    G[L].append((R, -D))
    G[R].append((L, +D))

ans = [None] * (N + 1)

def calc(i):
    ans[i] = 0
    stack = [i]
    while stack:
        now = stack.pop()
        for next_, d in G[now]:
            if ans[next_] == None:
                ans[next_] = ans[now] + d
                stack.append(next_)
            else:
                if ans[now] + d != ans[next_]:
                    return False
    return True

for i in range(1, N + 1):
    if ans[i] == None:
        if calc(i):
            pass
        else:
            print ('No')
            return


max_ = -10 ** 10
min_ = +10 ** 10
for i in ans[1:]:
    max_ = max(max_, i)
    min_ = min(min_, i)

if max_ - min_ > 10 ** 9:
    print ('No')
else:
    print ('Yes')


def dijkstra(node, edge, check):
    """
    nodeを含む連結グラフの中で、
    矛盾が発生しないか確認する
    矛盾が発生しない場合、
    nodeを0としたときの各ノードのスコアを返す
    """
    # 到達距離
    d = dict()
    st = [(node, 0)]
    curr_min = float('inf')
    curr_max = -float('inf')
    while st:
        curr_node, curr_d = st.pop()
        # 到達済みであれば矛盾が発生しないか確認する
        if curr_node in d.keys():
            if d[curr_node] != curr_d:
                # 矛盾が発生した
                return None, None, None, check
            else:
                continue
        # 到達した距離を記録
        d[curr_node] = curr_d 
        check[curr_node] = True
        if curr_d < curr_min:
            curr_min = curr_d
        if curr_max < curr_d:
            curr_max = curr_d

        # 隣接ノードを積む
        for nxt, diff in edge[curr_node]:
            st.append((nxt, curr_d + diff))
    
    return d, curr_min, curr_max, check


def submit():
    n, m = (int(e) for e in input().split())
    
    # グラフを構成
    edge = {i : [] for i in range(1, n + 1)}
    for _ in range(m):
        l, r, d = (int(e) for e in input().split())
        edge[l].append((r, d))
        edge[r].append((l, -d))

    check = {i: False for i in range(1, n + 1)}
    curr_max = -float('inf')

    for i in range(1, n + 1):
        if not check[i]:
            d, sub_min, sub_max, check = dijkstra(i, edge, check)

            if d == None:
                print('No')
                return
            # sub_minを0としたときのsub_maxを計算する
            sub_max -= sub_min
            if sub_max > curr_max:
                curr_max = sub_max

    if curr_max > 10 ** 9:
        print('No')
    else:
        print('Yes')


submit()

from collections import deque
N,M=map(int, input().split())
A=[[]for _ in range(N)]
V=[False]*N
X=[0]*N
x=0
for i in range(M):
  L,R,D=map(int, input().split())
  A[L-1].append((R-1,D))
  A[R-1].append((L-1,-D))
  
for i in range(N):
  if V[i]==False:
    stack=deque([(i,x)])
    V[i]=True
    while stack:
      now,dx=stack.popleft()
      for new,di in A[now]:
        if V[new]:
          if X[new]!=dx+di:
            print('No')
            return
        else:
          X[new]=dx+di
          V[new]=True
          stack.append((new,dx+di))

if max(X)-min(X)>10**9:
  print('No')
else:
  print('Yes')

# 人を頂点と見なしたグラフを作る。有向で、逆向きの場合は正負を反転させて辺を張る
# 頂点からの距離を記録し、一致しない箇所があればNG。
# 全ての辺を通るまで続ける。
# 辺の情報を[{0から行ける頂点},{1から行ける頂点},...]で管理する
# 親には進まないようにしてDFSする

N,M = list(map(int,input().split()))
E = [[] for i in range(N)]
for i in range(M):
  L,R,D = list(map(int,input().split()))
  E[L-1].append([R-1,D])
  E[R-1].append([L-1,-D])
from collections import deque
# 頂点、親、距離
INF = 10 ** 10
dist = [INF] * N
for i in range(N):
  if dist[i] != INF:
    continue
  dist[i] = 0
  q = deque()
  # 頂点、親
  q.append([i,-1])
  while q:
    v,parent = q.popleft()
    for child in E[v]:
      if child[0] == parent:
        continue
      if dist[child[0]] == INF:
        dist[child[0]] = dist[v] + child[1]
        q.append([child[0],v])
      else:
        if dist[child[0]] != dist[v] + child[1]:
          print("No")
          return
else:
  print("Yes")


n,m=list(map(int,input().split()))
G=[[] for i in range(n)]
for i in range(m):
  l,r,d=list(map(int,input().split()))
  G[l-1].append([r-1,d])
  G[r-1].append([l-1,-d])

dist=[None]*n
from collections import deque
for i in range(n):
  q=deque()
  if dist[i]==None:
    dist[i]=0
    q.append(i)
  while q:
    cur=q.popleft()
    for nx,nxd in G[cur]:
      if dist[nx]==None:
        dist[nx]=dist[cur]+nxd
        q.append(nx)
      elif dist[nx]!=dist[cur]+nxd:
        print("No")
        return
print("Yes")



N, M = list(map(int, input().split()))

links = [[] for _ in range(N + 1)]
for _ in range(M):
    L, R, D = list(map(int, input().split()))
    links[L].append((R, D))
    links[R].append((L, -D))

t = [None] * (N + 1)
for i in range(1, N + 1):
    if t[i] is not None:
        continue
    t[i] = 0
    s = [i]
    while s:
        j = s.pop()
        for k, l in links[j]:
            if t[k] is None:
                t[k] = t[j] + l
                s.append(k)
            else:
                if t[k] != t[j] + l:
                    print('No')
                    return
print('Yes')


import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return x,self.dist[x]
        else:
            tmp=self.find(self.parents[x])
            self.parents[x]=tmp[0]
            self.dist[x]+=tmp[1]
            return self.parents[x],self.dist[x]
    
    def union(self,x,y,d):
        rx=self.find(x)[0]
        ry=self.find(y)[0]
        diff=self.dist[y]-self.dist[x]-d
        if rx==ry:
            if diff!=0:
                return True
            return False
        if diff<0:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
        self.parents[rx]=ry
        self.dist[rx]=diff
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        print('Yes')
def __starting_point():
    main()

__starting_point()

#!/usr/bin/env python3
import sys

YES = "Yes"  # type: str
NO = "No"  # type: str


def solve(N: int, M: int, L: "List[int]", R: "List[int]", D: "List[int]"):
    uf = UnionFind(N+1)
    try:
        for l, r, d in zip(L, R, D):
            uf.merge(l, r, d)
        return YES
    except MergeError:
        return NO

# Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools
def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  # type: int
    M = int(next(tokens))  # type: int
    L = [int()] * (M)  # type: "List[int]"
    R = [int()] * (M)  # type: "List[int]"
    D = [int()] * (M)  # type: "List[int]"
    for i in range(M):
        L[i] = int(next(tokens))
        R[i] = int(next(tokens))
        D[i] = int(next(tokens))
    print((solve(N, M, L, R, D)))
    
class MergeError(Exception):
    pass

# 参考: https://qiita.com/drken/items/cce6fc5c579051e64fab
class UnionFind:
    def __init__(self, size: int):
        self.par = list(range(size))
        self.rank = [0] * size
        self.diff_weight = [0] * size

    def root(self, x: int):
        if self.par[x] == x:
            return x
        r = self.root(self.par[x])
        self.diff_weight[x] += self.diff_weight[self.par[x]] # 累積和をとる        
        #return par[x] := r
        self.par[x] = r
        return r

    def weight(self, x: int):
        self.root(x) # 経路圧縮
        return self.diff_weight[x]

    def same(self, x: int, y: int):
        return self.root(x) == self.root(y)

    # weight(y) - weight(x) = w となるように merge する
    def merge(self, x: int, y: int, w: int):
        # x と y それぞれについて、 root との重み差分を補正
        adjusted_w = w + self.weight(x) - self.weight(y)
        x = self.root(x)
        y = self.root(y)
        if x == y:
            if adjusted_w != 0:
                raise MergeError
            return
        if self.rank[x] < self.rank[y]:
            x, y, adjusted_w = y, x, -adjusted_w
        if self.rank[x] == self.rank[y]:
            self.rank[x] += 1
        self.par[y] = x
        self.diff_weight[y] = adjusted_w

def test():
    import doctest
    doctest.testmod()

def __starting_point():
    #test()
    main()

__starting_point()

import sys
from collections import deque

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


class UnionFindWeighted:
    # Reference:
    # https://note.nkmk.me/python-union-find/
    # https://at274.hatenablog.com/entry/2018/02/03/140504
    # https://qiita.com/drken/items/cce6fc5c579051e64fab
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.weight = [0] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            root = self.find(self.parents[x])
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = root
            return root

    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)

        if rx == ry:
            return

        if self.parents[rx] > self.parents[ry]:
            x, y, rx, ry, w = y, x, ry, rx, -w

        self.parents[rx] += self.parents[ry]
        self.parents[ry] = rx
        self.weight[ry] = self.weight[x] - self.weight[y] + w

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def diff(self, x, y):
        return self.weight[y] - self.weight[x]


def main():
    N, M, *LRD = list(map(int, read().split()))

    uf = UnionFindWeighted(N)
    for l, r, d in zip(*[iter(LRD)] * 3):
        l -= 1
        r -= 1
        if uf.same(l, r) and uf.diff(l, r) != d:
            print('No')
            return
        else:
            uf.union(l, r, d)

    print('Yes')
    return


def __starting_point():
    main()

__starting_point()

from collections import namedtuple, deque

class Person:
    def __init__(self, id, conn, x):
        self.id = id
        self.conn = conn
        self.x = x

def main():
    with open(0) as f:
        N, M = map(int, f.readline().split())
        info = [tuple(map(int, line.split())) for line in f.readlines()]
    people = [Person(i, conn=[], x=None) for i in range(N)]
    for l, r, d in info:
        people[l-1].conn.append((r-1, d))
        people[r-1].conn.append((l-1, -d))
    
    for person in people:
        if person.x is not None:
            continue
        else:
            person.x = person.id
            #bfs
            reserved = deque([person])
            seen = {person.id}
            while len(reserved) > 0:
                current = reserved.popleft()
                for next_person_id, d in current.conn:
                    if people[next_person_id].x is None:
                        people[next_person_id].x = current.x + d
                    else:
                        if people[next_person_id].x != current.x + d:
                            print('No')
                            return None
                    if next_person_id in seen:
                        continue
                    seen.add(next_person_id)
                    reserved.append(people[next_person_id])
    print('Yes')

main()            

#!/usr/bin/env python3
class WeightedUnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.weight = [0] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            px = self.find(self.parents[x])
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = px
            return px

    def union(self, x, y, w):
        w += self.weight[x] - self.weight[y]
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y = y, x
            w = -w
        self.parents[x] += self.parents[y]
        self.parents[y] = x
        self.weight[y] = w
        return

    def weig(self, x):
        self.find(x)
        return self.weight[x]

    def diff(self, x, y):
        return self.weight[y] - self.weight[x]

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)


n, m = map(int, input().split())
UF = WeightedUnionFind(n)

for i in range(m):
    l, r, d = map(int, input().split())
    l -= 1;r -= 1
    if UF.same(l, r):
        if d != abs(UF.diff(l, r)):
            print("No");return
    else:
        UF.union(l, r, d)
print("Yes")

N, M = map(int, input().split())

graph = [[] for i in range(N)]
left = set()
right = set()
for i in range(M):
  l, r, d = map(int, input().split())
  l -= 1; r -= 1
  graph[l].append((r, d))
  graph[r].append((l, -d))
  left.add(l); right.add(r)

root = left - right
if M and len(root) == 0:
  print('No')
  return

X = [None] * N
while root:
  node = root.pop()
  X[node] = 0
  stack = [node]
  while stack:
    node = stack.pop()
    while graph[node]:
      child, d = graph[node].pop()
      if X[child] is None:
        X[child] = X[node] + d
        stack.append(child)
      elif X[child] != X[node] + d:
        print('No')
        return

print('Yes')

#!/usr/bin/env python3
class WeightedUnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.weight = [0] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            px = self.find(self.parents[x])
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = px
            return px

    def union(self, x, y, w):
        w += self.weight[x] - self.weight[y]
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y = y, x
            w = -w
        self.parents[x] += self.parents[y]
        self.parents[y] = x
        self.weight[y] = w
        return

    def weig(self, x):
        self.find(x)
        return self.weight[x]

    def diff(self, x, y):
        return self.weight[y] - self.weight[x]

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)


n, m = map(int, input().split())
UF = WeightedUnionFind(n + 1)

for i in range(m):
    l, r, d = map(int, input().split())
    if UF.same(l, r):
        if d != abs(UF.diff(l, r)):
            print("No");return
    else:
        UF.union(l, r, d)
print("Yes")

import sys

sys.setrecursionlimit(10 ** 6)
INF = float("inf")
MOD = 10 ** 9 + 7


def input():
    return sys.stdin.readline().strip()


class WeightedUnionFind:
    def __init__(self, n_nodes):
        self.n_nodes = n_nodes
        self.parents = [-1] * n_nodes

        # 親への重みを管理
        self.weights = [0] * n_nodes

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            parent = self.find(self.parents[x])
            self.weights[x] += self.weights[self.parents[x]]
            self.parents[x] = parent
            return parent

    # xからyへの重みがw
    def unite(self, x, y, w):
        w += self.weights[x]
        w -= self.weights[y]
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x
            w *= -1

        self.parents[x] += self.parents[y]
        self.parents[y] = x
        self.weights[y] = w
        return

    def is_same(self, x, y):
        return self.find(x) == self.find(y)

    def get_size(self, x):
        return -self.parents[self.find(x)]

    def get_weight(self, x, y):
        return self.weights[y] - self.weights[x]


def main():
    N, M = list(map(int, input().split()))
    tree = WeightedUnionFind(N)
    for _ in range(M):
        L, R, D = list(map(int, input().split()))
        L -= 1
        R -= 1

        if tree.is_same(L, R):
            if tree.get_weight(L, R) == D:
                continue
            else:
                print("No")
                return
        else:
            tree.unite(L, R, D)

    print("Yes")
    return


def __starting_point():
    main()

__starting_point()

#!/usr/bin/env python3
import sys
sys.setrecursionlimit(200002)

n, m = list(map(int, input().split()))

graph = [[] for i in range(n)]
for i in range(m):
    l, r, d = list(map(int, input().split()))

    graph[l-1].append([r-1, d])
    graph[r-1].append([l-1, -d])
# print(graph)


def dfs(s):
    for t, d in graph[s]:
        if x[t] is None:
            x[t] = x[s]+d
            if not dfs(t):
                return False
        else:
            if x[t]-x[s] != d:
                return False
    return True


x = [None]*n
ans = True
for i in range(n):
    if x[i] is None:
        x[i] = 0
        if not dfs(i):
            ans = False

print((('No', 'Yes')[ans]))


class WeightedUF:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [0] * n
        self.weight = [0] * n

    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y

    def unite(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)

        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        else:
            self.par[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def diff(self, x, y):
        return self.weight[x] - self.weight[y]

n,m=map(int,input().split())
wuf=WeightedUF(n)
for i in range(m):
    l,r,d=map(int,input().split())
    l-=1
    r-=1
    if wuf.same(l,r):
        if wuf.diff(l,r)!=d:
            print("No")
            return
    else:
        wuf.unite(l,r,d)
print("Yes")

import numpy as np


def inputs(func=lambda x: x, sep=None, maxsplit=-1):
	return list(map(func, input().split(sep=sep, maxsplit=maxsplit)))

def input_row(n : int, type=np.int, *args, **kwargs):
	return np.fromiter(inputs(type, *args, **kwargs), dtype=type)

def input_2d(nrows : int, ncols : int, type=np.int, *args, **kwargs):
	data = np.zeros((nrows, ncols), dtype=type)
	for i in range(nrows):
		data[i, :] = input_row(ncols, type, *args, **kwargs)
	return data

class Repeat (object):
	__slots__ = [
		'element',
		'times'
	]
	
	def __init__(self, element, times : int):
		self.element = element
		self.times = int(times)
	
	def __len__(self):
		return self.times
	
	def __iter__(self):
		return iter(self.element for _ in range(self.times))

def repeat(element, times : int):
	return Repeat(element, times)

class IntAddition (object):
	'''整数の加法'''
	def operate(self, x, y):
		return x + y
	@property
	def identity(self):
		return 0
	def cancel(self, x, y):
		return x - y
	def invert(self, x):
		return -x
	def accumulate(self, x, count):
		return x * count

class UnionFind (object):
	'''重み付きUnion-Find木'''
	def __init__(
			self,
			num_nodes=0,
			abelian_operator=IntAddition()):
		self.parent = []
		self.potential = []
		self.op = abelian_operator
		
		self.extend(num_nodes)
	
	def append(self):
		self.parent.append(-1)
		self.potential.append(self.op.identity)
	
	def extend(self, num_nodes):
		self.parent.extend(repeat(-1, num_nodes))
		self.potential.extend(repeat(self.op.identity, num_nodes))
	
	def root(self, x):
		parent = self.parent[x]
		if 0 <= parent:
			self.parent[x] = self.root(parent)
			self.potential[x] = self.op.operate(
				self.potential[x], self.potential[parent]
			)
			x = self.parent[x]
		return x
	
	def difference_from_root_to(self, x):
		self.root(x)
		return self.potential[x]
		
	def size(self, x):
		return -self.parent[self.root(x)]
	
	def difference(self, x, y):
		if not self.issame(x, y):
			raise RuntimeError('x と y は同じ集合に属していません。')
		return self.op.cancel(
			self.difference_from_root_to(y),
			self.difference_from_root_to(x)
		)
	
	def unite(self, x, y, difference=None):
		if difference is None:
			difference = self.op.identity
		
		x, px = self.root(x), self.potential[x]
		y, py = self.root(y), self.potential[y]
		difference = self.op.cancel(difference, py)
		difference = self.op.operate(difference, px)
		if x == y:
			return difference == 0
		
		if self.size(x) < self.size(y):
			x, y = y, x
			difference = self.op.invert(difference)
		self.parent[x] += self.parent[y]
		self.parent[y] = x
		self.potential[y] = difference
		
		return True
	
	def issame(self, x, y):
		return self.root(x) == self.root(y)



N, M = inputs(int)
uf = UnionFind(num_nodes=N)

valid = True
for i in range(M):
	L, R, D = inputs(int)
	L -= 1
	R -= 1
	
	if not uf.unite(L, R, D):
		valid = False

print(('Yes' if valid else 'No'))


import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
class Unionfind():
    def __init__(self,n):
        self.parents=[-1]*n
        self.dist=[0]*n 
    
    def find(self,x):
        if self.parents[x]<0:
            return self.dist[x],x
        else:
            tmp=self.find(self.parents[x])
            self.dist[x]+=tmp[0]
            self.parents[x]=tmp[1]
            return self.dist[x],self.parents[x]
    
    def union(self,x,y,d):
        rx=self.find(x)[1]
        ry=self.find(y)[1]
        diff=self.dist[y]-self.dist[x]-d
        if rx==ry:
            if diff!=0:
                return True
            return False
        if diff<0:
            rx,ry=ry,rx
            diff=-diff
        self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
        self.parents[rx]=ry
        self.dist[rx]=diff
        return False
    
def main():
    n,m,*lrd=list(map(int,read().split()))
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        print('Yes')
def __starting_point():
    main()

__starting_point()

from collections import deque

def dfs(s):
    stack = deque([s])
    dist[s] = 0
    while stack:
        v = stack.pop()
        for d, u in E[v]:
            if dist[u] is None:
                dist[u] = dist[v] + d
                stack.append(u)
            else:
                if dist[u] != dist[v] + d:
                    return False
    return True

N, M = map(int, input().split())
E = [[] for _ in range(N)]
for _ in range(M):
    l, r, d = map(int, input().split())
    E[l-1].append((d, r - 1))
    E[r-1].append((-d, l - 1))
dist = [None] * N
for i in range(N):
    if dist[i] is not None:
        continue
    if not dfs(i):
        print('No')
        break
else:
    print('Yes')

from collections import deque
import sys
sys.setrecursionlimit(10**7)
input = sys.stdin.readline
inf = pow(10, 10)

n, m = list(map(int, input().split()))
a = [inf] * n

edge = [[] for i in range(n)]

for i in range(m):
    l, r, d = list(map(int, input().split()))
    l-=1;r-=1
    edge[l].append((r, d))
    edge[r].append((l, -d))

"""
# BFS解放
flag = True
dist = [inf] * n
for i in range(n):
    if not flag: break
    if dist[i] == inf: # 偽の場合、連結で既に訪れている
        dist[i] = 0
        dq = deque([i])
        while dq:
            now = dq.popleft()
            for e in edge[now]:
                nnode, d = e
                if dist[nnode] == inf:
                    dist[nnode] = dist[now] + d
                    dq.append(nnode)
                else:
                    if dist[nnode] != dist[now] + d:
                        flag = False
                        break
if flag:
    print('Yes')
else:
    print('No')
"""

# DFS解法
dist = [inf]*n
def dfs(i, totald = 0):
    if dist[i] < inf:
        if dist[i] == totald:
            return True
        else:
            return False
    dist[i] = totald
    for e in edge[i]:
        nnode, d = e
        if not dfs(nnode, totald+d):
            return False
    return True


f = True
for i in range(n):
    if dist[i] == inf:
        if not dfs(i, 0):
            f = False
            break
if f:
    print('Yes')
else:
    print('No')


#!/usr/bin/env python3
class WeightedUnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.weight = [0] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            px = self.find(self.parents[x])
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = px
            return px

    def union(self, x, y, w):
        w += self.weight[x] - self.weight[y]
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x, y, w = y, x, -w
        self.parents[x] += self.parents[y]
        self.parents[y] = x
        self.weight[y] = w
        return

    def weig(self, x):
        self.find(x)
        return self.weight[x]

    def diff(self, x, y):
        return self.weig(y) - self.weig(x)
    
    def same(self, x, y):
        return self.find(x) == self.find(y)

(n, m), *q = [[*map(int, o.split())] for o in open(0)]
UF = WeightedUnionFind(n + 1)
for l, r, d in q:
    if UF.same(l, r):
        if d != abs(UF.diff(l, r)):
            print("No"); return
    else:
        UF.union(l, r, d)
print("Yes")

import sys
import numpy as np


def inputs(func=lambda x: x, sep=None, maxsplit=-1):
	return list(map(func, sys.stdin.readline().split(sep=sep, maxsplit=maxsplit)))

def input_row(n : int, type=np.int, *args, **kwargs):
	return np.fromiter(inputs(type, *args, **kwargs), dtype=type)

def input_2d(nrows : int, ncols : int, type=np.int, *args, **kwargs):
	data = np.zeros((nrows, ncols), dtype=type)
	for i in range(nrows):
		data[i, :] = input_row(ncols, type, *args, **kwargs)
	return data

class IntAddition (object):
	'''整数の加法'''
	def operate(self, x, y):
		return x + y
	@property
	def identity(self):
		return 0
	def cancel(self, x, y):
		return x - y
	def invert(self, x):
		return -x
	def accumulate(self, x, count):
		return x * count

class UnionFindNode (object):
	__slots__ = [
		'parent_index',
		'size',
		'difference_from_parent'
	]
	
	def __init__(self, index : int, potential_identity):
		self.parent_index = index
		self.size = 1
		self.difference_from_parent = potential_identity

class UnionFind (object):
	'''重み付きUnion-Find木'''
	def __init__(
			self,
			num_nodes=0,
			potential_abelian=IntAddition()):
		self.nodes = []
		self.op = potential_abelian
		
		self.extend(num_nodes)
	
	def append(self):
		self.nodes.append(
			UnionFindNode(len(self.nodes), self.op.identity)
		)
		
	def extend(self, num_nodes):
		self.nodes.extend(
			UnionFindNode(i, self.op.identity)
			for i in range(num_nodes)
		)
	
	def root(self, index : int):
		x = self.nodes[index]
		
		while x.parent_index != index:
			parent = self.nodes[x.parent_index]
			x.difference_from_parent = self.op.operate(
				x.difference_from_parent,
				parent.difference_from_parent
			)
			index = x.parent_index = parent.parent_index
			x = self.nodes[index]
		
		return index
	
	def difference_from_root_to(self, index : int):
		x = self.nodes[index]
		potential = x.difference_from_parent
		
		while x.parent_index != index:
			parent = self.nodes[x.parent_index]
			potential = self.op.operate(
				potential,
				parent.difference_from_parent
			)
			index = x.parent_index
			x = self.nodes[index]
		
		return potential
		
	def size(self, index : int):
		return self.nodes[self.root(index)].size
	
	def difference(self, x, y):
		if not self.issame(x, y):
			raise RuntimeError('x と y は同じ集合に属していません。')
		return self.op.cancel(
			self.difference_from_root_to(y),
			self.difference_from_root_to(x)
		)
	
	def unite(self, x, y, difference=None) -> bool:
		if difference is None:
			difference = self.op.identity
		
		x, px = self.root(x), self.difference_from_root_to(x)
		y, py = self.root(y), self.difference_from_root_to(y)
		if x == y:
			return difference == self.op.cancel(py, px)
		
		difference = self.op.cancel(difference, py)
		difference = self.op.operate(difference, px)
		
		if self.size(x) < self.size(y):
			x, y = y, x
			difference = self.op.invert(difference)
		
		x_node = self.nodes[x]
		y_node = self.nodes[y]
		x_node.size += y_node.size
		y_node.parent_index = x
		y_node.difference_from_parent = difference
		
		return True
	
	def issame(self, x, y):
		return self.root(x) == self.root(y)



N, M = inputs(int)
uf = UnionFind(num_nodes=N)

valid = True
for i in range(M):
	L, R, D = inputs(int)
	L -= 1
	R -= 1
	
	valid = valid and uf.unite(L, R, D)

print(('Yes' if valid else 'No'))


from collections import deque

def bfs():
    visit = [0] * (n + 1)
    e = [0] * (m + 1)
    x = [0] * (n + 1)
    q = deque()
    for i in range(1, n + 1):
        if not visit[i]:
            q.append(i)
            visit[i] = 1
            while q:
                j = q.popleft()
                for g in G[j]:
                    if not e[g[2]]:
                        #print(e, visit, q, x, j)
                        e[g[2]] = 1
                        if not visit[g[0]]:
                            x[g[0]] = g[1] + x[j]
                            visit[g[0]] = 1
                            q.append(g[0])
                        else:
                            #print(x[g[0]], g[1] + x[j])
                            if not x[g[0]] == g[1] + x[j]:
                                return False
    return True

n, m = map(int, input().split())
G = [[] for _ in range(n + 1)]
for i in range(m):
    l, r, d = map(int, input().split())
    G[l].append([r, d, i])
    G[r].append([l, -d, i])
print("Yes" if bfs() else "No")

N,M = map(int,input().split())
LRD = [tuple(map(int,input().split())) for i in range(M)]

class WeightedUnionFind:
    def __init__(self,N):
        self.parent = [i for i in range(N)]
        self.rank = [0] * N
        self.count = 0
        self.weight = [0] * N
    def root(self,a):
        if self.parent[a] == a:
            return a
        else:
            pa = self.root(self.parent[a])
            self.weight[a] += self.weight[self.parent[a]]
            self.parent[a] = pa
            return pa
    def is_same(self,a,b):
        return self.root(a) == self.root(b)
    def unite(self,a,b,w):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self.rank[ra] < self.rank[rb]:
            self.parent[ra] = rb
            self.weight[ra] = w - self.weight[a] + self.weight[b]
        else:
            self.parent[rb] = ra
            self.weight[rb] = -w - self.weight[b] + self.weight[a]
            if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
        self.count += 1
    def diff(self,a,b):
        return self.weight[a] - self.weight[b]

uf = WeightedUnionFind(N)
for l,r,d in LRD:
    l,r = l-1,r-1
    if uf.is_same(l,r):
        if uf.diff(l,r) != d:
            print('No')
            return
    else:
        uf.unite(l,r,d)
print('Yes')

from sys import stdin
from collections import deque
def main():
    #入力
    readline=stdin.readline
    n,m=map(int,readline().split())
    G=[[] for _ in range(n+1)]
    for i in range(m):
        l,r,d=map(int,readline().split())
        G[l].append((r,d))
        G[r].append((l,-d))

    flags=[False]*(n+1)
    flags[0]=True
    inf=10**10
    x=[-inf]*(n+1)
    q=deque([])
    ans=True
    for i in range(1,n+1):
        if ans==False: break
        if flags[i]==False:
            x[i]=0
            flags[i]=True
            q.append(i)
            while len(q)>0:
                now=q.popleft()
                for t in G[now]:
                    nex=t[0]
                    cost=t[1]
                    if x[nex]==-inf:
                        x[nex]=x[now]+cost
                    else:
                        if x[nex]!=x[now]+cost:
                            ans=False
                            break
                    if flags[nex]==False:
                        flags[nex]=True
                        q.append(nex)

    print("Yes" if ans else "No")

def __starting_point():
    main()
__starting_point()

import numpy as np


def inputs(func=lambda x: x, sep=None, maxsplit=-1):
	return list(map(func, input().split(sep=sep, maxsplit=maxsplit)))

def input_row(n : int, type=np.int, *args, **kwargs):
	return np.fromiter(inputs(type, *args, **kwargs), dtype=type)

def input_2d(nrows : int, ncols : int, type=np.int, *args, **kwargs):
	data = np.zeros((nrows, ncols), dtype=type)
	for i in range(nrows):
		data[i, :] = input_row(ncols, type, *args, **kwargs)
	return data

from itertools import repeat

class IntAddition (object):
	'''整数の加法'''
	def operate(self, x, y):
		return x + y
	@property
	def identity(self):
		return 0
	def cancel(self, x, y):
		return x - y
	def invert(self, x):
		return -x
	def accumulate(self, x, count):
		return x * count

class UnionFind (object):
	'''重み付きUnion-Find木'''
	def __init__(
			self,
			num_nodes=0,
			abelian_operator=IntAddition()):
		self.parent = []
		self.potential = []
		self.op = abelian_operator
		
		self.extend(num_nodes)
	
	def append(self):
		self.parent.append(-1)
		self.potential.append(self.op.identity)
	
	def extend(self, num_nodes):
		self.parent.extend(repeat(-1, num_nodes))
		self.potential.extend(repeat(self.op.identity, num_nodes))
	
	def root(self, x):
		parent = self.parent[x]
		if 0 <= parent:
			self.parent[x] = self.root(parent)
			self.potential[x] = self.op.operate(
				self.potential[x], self.potential[parent]
			)
			x = self.parent[x]
		return x
	
	def difference_from_root_to(self, x):
		self.root(x)
		return self.potential[x]
		
	def size(self, x):
		return -self.parent[self.root(x)]
	
	def difference(self, x, y):
		if not self.issame(x, y):
			raise RuntimeError('x と y は同じ集合に属していません。')
		return self.op.cancel(
			self.difference_from_root_to(y),
			self.difference_from_root_to(x)
		)
	
	def unite(self, x, y, difference=None):
		if difference is None:
			difference = self.op.identity
		
		x, px = self.root(x), self.potential[x]
		y, py = self.root(y), self.potential[y]
		difference = self.op.cancel(difference, py)
		difference = self.op.operate(difference, px)
		if x == y:
			return difference == 0
		
		if self.size(x) < self.size(y):
			x, y = y, x
			difference = self.op.invert(difference)
		self.parent[x] += self.parent[y]
		self.parent[y] = x
		self.potential[y] = difference
		
		return True
	
	def issame(self, x, y):
		return self.root(x) == self.root(y)



N, M = inputs(int)
uf = UnionFind(num_nodes=N)

valid = True
for i in range(M):
	L, R, D = inputs(int)
	L -= 1
	R -= 1
	
	if not uf.unite(L, R, D):
		valid = False

print(('Yes' if valid else 'No'))


def main():
    from collections import deque
    import sys
    input = sys.stdin.readline

    N, M = list(map(int, input().split()))

    g = tuple(set() for _ in range(N))
    h = [0] * N  # 入り次数
    for _ in range(M):
        L, R, D = list(map(int, input().split()))
        L -= 1
        R -= 1
        g[L].add((R, D))
        h[R] += 1

    dist = [-1] * N

    def dfs(s):
        dist[s] = 0
        dq = deque([s])
        while dq:
            v = dq.popleft()
            for u, d in g[v]:
                if ~dist[u]:
                    if dist[u] != dist[v] + d:
                        return False
                else:
                    dist[u] = dist[v] + d
                    dq.append(u)
        return True

    # 始点からのパスを処理
    for s in range(N):
        if h[s]: continue  # sに入ってくるパスがあるので、sを始点にしない
        if ~dist[s]: continue
        if not dfs(s):
            print('No')
            return

    # サイクルを処理（どの点も入るパスがあり、処理できていない）
    for s in range(N):
        if ~dist[s]: continue
        if not dfs(s):
            print('No')
            return

    print('Yes')


def __starting_point():
    main()

__starting_point()

# 人を頂点と見なしたグラフを作る。有向で、逆向きの場合は正負を反転させて辺を張る
# 頂点からの距離を記録し、一致しない箇所があればNG。
# 全ての辺を通るまで続ける。
# 辺の情報を[{0から行ける頂点},{1から行ける頂点},...]で管理する
# 親には進まないようにしてDFSする

N,M = list(map(int,input().split()))
E = [[] for i in range(N)]
for i in range(M):
  L,R,D = list(map(int,input().split()))
  E[L-1].append([R-1,D])
  E[R-1].append([L-1,-D])
from collections import deque
# 頂点、親、距離
INF = 10 ** 10
dist = [INF] * N
for i in range(N):
  if dist[i] != INF:
    continue
  dist[i] = 0
  q = deque()
  # 頂点、親
  q.append([i,-1])
  while q:
    v,parent = q.pop()
    for child in E[v]:
      if child[0] == parent:
        continue
      if dist[child[0]] == INF:
        dist[child[0]] = dist[v] + child[1]
        q.append([child[0],v])
      else:
        if dist[child[0]] != dist[v] + child[1]:
          print("No")
          return
else:
  print("Yes")


import sys
sys.setrecursionlimit(10**9)

read=sys.stdin.read
    
def main():
    class Unionfind():
        def __init__(self,n):
            self.parents=[-1]*n
            self.dist=[0]*n 
        
        def find(self,x):
            if self.parents[x]<0:
                return self.dist[x],x
            else:
                tmp=self.find(self.parents[x])
                self.dist[x]+=tmp[0]
                self.parents[x]=tmp[1]
            return self.dist[x], self.parents[x]
        
        def union(self,x,y,d):
            rx=self.find(x)[1]
            ry=self.find(y)[1]
            diff=self.dist[y]-self.dist[x]-d
            if rx==ry:
                if diff!=0:
                    return True
                return False
            if diff<0:
                rx,ry=ry,rx
                diff=-diff
            self.parents[ry]=min(self.parents[ry],self.parents[rx]-diff)
            self.parents[rx]=ry
            self.dist[rx]=diff
            return False
    n,m,*lrd=list(map(int,read().split()))
    edg=[]
    v=Unionfind(n)
    for l,r,d in zip(*[iter(lrd)]*3):
        if v.union(l-1,r-1,d):
            print('No')
            break
    else:
        if max(-d-1 for d in v.parents if d<0) >10**9:
            print('No')
        else:
            print('Yes')
def __starting_point():
    main()

__starting_point()

from collections import deque
n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    l, r, d = map(int, input().split())
    graph[l-1].append((r-1, d))
    graph[r-1].append((l-1, -d))
seen = [False]*n
dist = [None]*n
for i in range(n):
    if seen[i]:
        continue
    q = deque([i])
    dist[i] = 0
    while q:
        node = q.popleft()
        if seen[node]:
            continue
        seen[node] = True
        for c_node, d in graph[node]:
            if dist[c_node] is None:
                dist[c_node] = dist[node] + d
            elif dist[c_node] != dist[node] + d:
                print('No')
                return
            if not seen[c_node]:
                q.append(c_node)
print('Yes')

n,m=list(map(int,input().split()))
lrd=[tuple(map(int,input().split())) for i in range(m)]

class WeightedUnionFind:
  def __init__(self,n):
    self.parent = [i for i in range(n)]
    self.rank = [0] * n
    self.count = 0
    self.weight = [0] * n
  def root(self,a):
    if self.parent[a] == a:
      return a
    else:
      pa = self.root(self.parent[a])
      self.weight[a] += self.weight[self.parent[a]]
      self.parent[a] = pa
      return pa
  def is_same(self,a,b):
    return self.root(a) == self.root(b)
  def unite(self,a,b,w):
    ra = self.root(a)
    rb = self.root(b)
    if ra == rb: return
    if self.rank[ra] < self.rank[rb]:
      self.parent[ra] = rb
      self.weight[ra] = w - self.weight[a] + self.weight[b]
    else:
      self.parent[rb] = ra
      self.weight[rb] = -w - self.weight[b] + self.weight[a]
      if self.rank[ra] == self.rank[rb]: self.rank[ra] += 1
    self.count += 1
  def diff(self,a,b):
    return self.weight[a] - self.weight[b]

uf=WeightedUnionFind(n)
for l,r,d in lrd:
  l,r=l-1,r-1
  if uf.is_same(l,r):
    if uf.diff(l,r)!=d:
      print('No')
      return
  else:
      uf.unite(l,r,d)
print('Yes')


from collections import deque
N,M = map(int, input().split())
E = [[] for _ in range(N)]
for _ in range(M):
  l,r,d = map(int, input().split())
  l,r = l-1,r-1
  E[l].append((r,d))
  E[r].append((l,-d)) 
  
#for e in E:
#  print(e)
  
# bfs
Q = deque()
visited = [False] * N
willSearch = [False] * N
INF = 10**16
A = [ INF ] * N

for i in range(N):
  if visited[i]:
    continue
  Q.append((i,-1,0))
  while Q:
    now, prev, num = Q.popleft()
    visited[now] = True
    if A[now] == INF:
      A[now] = num
    elif A[now] != num:
      # ある点において2通りのnum設定の仕方がある
      #print(now,prev,num,A[inxt])
      print("No")
      return
    for nxt, dis in E[now]:
      if nxt == prev:
        continue
      if A[nxt] < INF and A[nxt] != num + dis:
        # ある点において2通りのnum設定の仕方がある
        #print(now,prev,num, nxt,dis, A[nxt])
        print("No")
        return
      if visited[nxt] or willSearch[nxt]:
        continue
      Q.append((nxt, now, num + dis))
      willSearch[nxt] = True
    
print("Yes")

from collections import deque

N, M = list(map(int, input().split()))

G = [[] for _ in range(N)]
for i in range(M):
  L, R, D = list(map(int, input().split()))
  G[L-1].append((R-1, D))
  G[R-1].append((L-1, -D))
  
visited = [False] * N
xs = [0] * N
xs[0] = 0
x = 0
for i in range(N):
  if visited[i]:
    continue
  stack = deque([(i, x)])
  visited[i] = True
  while stack:
    now, xi = stack.popleft()
    for nx, di in G[now]:
      if visited[nx]:
        if xs[nx] != xi + di:
          print('No')
          return
      else:
        xs[nx] = xi + di
        visited[nx] = True
        stack.append((nx, xi+di))
        
if max(xs)-min(xs) > 1000000000:
  print('No')
else:
  print('Yes')



import sys
from typing import List, Optional

sys.setrecursionlimit(1000000)

N, M = list(map(int, input().split()))

g = [[] for _ in range(N)]

for i in range(M):
    l, r, d = list(map(int, input().split()))
    l -= 1
    r -= 1
    g[l].append((r, d))
    g[r].append((l, -d))


def ok(cur: int, ds: int, dists: List[Optional[int]]) -> bool:
    dists[cur] = ds

    flag = True
    for nx, d in g[cur]:
        if dists[nx] != None:
            flag &= dists[nx] - dists[cur] == d
        elif flag:
            flag &= ok(nx, ds + d, dists)

    return flag


dists = [None] * N
ans = True
for i in range(N):
    if ans and dists[i] == None:
        ans &= ok(i, 0, dists)

print(("Yes" if ans else "No"))


import sys
from collections import deque

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


class UnionFindWeighted:
    # Reference: https://note.nkmk.me/python-union-find/
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
        self.weight = [0] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            root = self.find(self.parents[x])
            self.weight[x] += self.weight[self.parents[x]]
            self.parents[x] = root
            return root

    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)

        if rx == ry:
            return

        if self.parents[rx] > self.parents[ry]:
            x, y, rx, ry, w = y, x, ry, rx, -w

        self.parents[rx] += self.parents[ry]
        self.parents[ry] = rx
        self.weight[ry] = self.weight[x] - self.weight[y] - w

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def diff(self, x, y):
        return self.weight[x] - self.weight[y]


def main():
    N, M, *LRD = list(map(int, read().split()))

    uf = UnionFindWeighted(N)
    for l, r, d in zip(*[iter(LRD)] * 3):
        l -= 1
        r -= 1
        if uf.same(l, r) and uf.diff(l, r) != d:
            print('No')
            return
        else:
            uf.union(l, r, d)

    print('Yes')
    return


def __starting_point():
    main()

__starting_point()

class WeightedUnionFind:
    def __init__(self, n):
        self.n = n
        self.par = list(range(n))
        self.rank = [0] * n
        self.weight = [0] * n
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y
    def unite(self, x, y, w):
        p, q = self.find(x), self.find(y)
        if self.rank[p] < self.rank[q]:
            self.par[p] = q
            self.weight[p] = w - self.weight[x] + self.weight[y]
        else:
            self.par[q] = p
            self.weight[q] = -w - self.weight[y] + self.weight[x]
            if self.rank[p] == self.rank[q]:
                self.rank[p] += 1
    def same(self, x, y):
        return self.find(x) == self.find(y)
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]
n, m = map(int, input().split())
UF = WeightedUnionFind(n)
for i in range(m):
    l, r, d = map(int, input().split())
    if UF.same(l - 1, r - 1):
        if UF.diff(l - 1, r - 1) != d:
            print("No");return
    else:
        UF.unite(l - 1, r - 1, d)
print("Yes")

from collections import deque
import sys
input = sys.stdin.readline
inf = pow(10, 10)

n, m = list(map(int, input().split()))
a = [inf] * n

edge = [[] for i in range(n)]

for i in range(m):
    l, r, d = list(map(int, input().split()))
    l-=1;r-=1
    edge[l].append((r, d))
    edge[r].append((l, -d))

flag = True
dist = [inf] * n
for i in range(n):
    if not flag: break
    if dist[i] == inf:
        dist[i] = 0
        dq = deque([i])
        while dq:
            now = dq.popleft()
            for e in edge[now]:
                nnode, d = e
                if dist[nnode] == inf:
                    dist[nnode] = dist[now] + d
                    dq.append(nnode)
                else:
                    if dist[nnode] != dist[now] + d:
                        flag = False
                        break
if flag:
    print('Yes')
else:
    print('No')


class WeightedUnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        # 根への距離を管理
        self.weight = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            # 親への重みを追加しながら根まで走査
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y

    # 併合
    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ yの木の高さ
        else:
            self.par[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            # 木の高さが同じだった場合の処理
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    # 同じ集合に属するか
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # xからyへのコスト
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]


N, M = map(int, input().split())
uf = WeightedUnionFind(N)

for _ in range(M):
    l, r, d = map(int, input().split())
    l -= 1
    r -= 1
    if uf.same(l, r):
        diff = uf.diff(l, r)
        if diff != d:
            print("No")
            return
    else:
        uf.union(l, r, d)

print("Yes")

class WeightedUnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        # 根への距離を管理
        self.weight = [0] * (n+1)

    # 検索
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            y = self.find(self.par[x])
            # 親への重みを追加しながら根まで走査
            self.weight[x] += self.weight[self.par[x]]
            self.par[x] = y
            return y

    # 併合
    def union(self, x, y, w):
        rx = self.find(x)
        ry = self.find(y)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ yの木の高さ
        else:
            self.par[ry] = rx
            self.weight[ry] = -w - self.weight[y] + self.weight[x]
            # 木の高さが同じだった場合の処理
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1

    # 同じ集合に属するか
    def same(self, x, y):
        return self.find(x) == self.find(y)

    # xからyへのコスト
    def diff(self, x, y):
        return self.weight[x] - self.weight[y]
    
n,m = map(int,input().split())
lrd = [[int(i) for i in input().split()] for j in range(m)]

ki = WeightedUnionFind(n)

for i in range(m):
    if ki.same(lrd[i][0],lrd[i][1]):
        if ki.diff(lrd[i][0],lrd[i][1]) != lrd[i][2]:
            print('No')
            return
    else:
        ki.union(lrd[i][0],lrd[i][1],lrd[i][2])
    
print('Yes')

# 深さ優先探索
from sys import stdin

N, M = list(map(int, stdin.readline().split()))

links = [[] for _ in range(N + 1)]
for _ in range(M):
    L, R, D = list(map(int, stdin.readline().split()))
    links[L].append((R, D))
    links[R].append((L, -D))

t = [None] * (N + 1)
for i in range(1, N + 1):
    if t[i] is not None:
        continue
    t[i] = 0
    s = [i]
    while s:
        j = s.pop()
        for k, l in links[j]:
            if t[k] is None:
                t[k] = t[j] + l
                s.append(k)
            else:
                if t[k] != t[j] + l:
                    print('No')
                    return
print('Yes')