CodeEff/ECCO huggingface dataset:
# Original solution
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


if __name__ == '__main__':
    main()


# Optimized solution
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


if __name__ == '__main__':
    main()
# Original solution
from collections import deque
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])

for i in range(n):
    dist=[None]*n
    q=deque()
    if dist[i]==None:
        dist[i]=0
    q.append(i)
    while q:
        cur=q.popleft()
        for nx,d in G[cur]:
            if dist[nx]==None:
                dist[nx]=dist[cur]+d
                q.append(nx)
            elif dist[nx]!=dist[cur]+d:
                print('No')
                exit()
print('Yes')


# Optimized solution
from collections import deque
n,m=list(map(int,input().split()))
G=[[] for i in range(n)]
dist=[None]*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])

for i in range(n):
    q=deque()
    if dist[i]==None:
        dist[i]=0
        q.append(i)
    while q:
        cur=q.popleft()
        for nx,d in G[cur]:
            if dist[nx]==None:
                dist[nx]=dist[cur]+d
                q.append(nx)
            elif dist[nx]!=dist[cur]+d:
                print('No')
                exit()
print('Yes')
# Original solution
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")
        exit(0)
print("Yes")



# Optimized solution
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')
      exit(0)
  else:
      uf.unite(l,r,d)
print('Yes')
# Original solution
import collections
from collections import deque
import sys
input = sys.stdin.readline

def tree(s):
    flag=True
    INF=-10**9
    dis = [INF for i in range(n)]
    dis[s]=0
    def bfs():
        d = deque()
        d.append(s)
        while len(d):
            x = d.popleft()
            for i,j in vec[x]:
                if dis[i] == INF:
                    dis[i]=dis[x]+j
                    d.append(i)
                else:
                    if dis[i]==dis[x]+j:
                        continue
                    else:
                        print('No')
                        exit()
        return flag
    return bfs()


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

for i in range(m):
    vec[a[i][0]-1].append((a[i][1]-1,a[i][2]))
    vec[a[i][1]-1].append((a[i][0]-1,-a[i][2]))

INF=float('inf')
visited=[INF]*n

for i in range(n):
    if visited[i]==INF:
        tree(i)
print('Yes')

# Optimized solution
import collections
from collections import deque
import sys
input = sys.stdin.readline

def bfs(s):
    d = deque()
    d.append(s)
    dis[s]=0
    flag=True
    while len(d):
        x = d.popleft()
        for i,j in vec[x]:
            if dis[i] == INF:
                dis[i]=dis[x]+j
                d.append(i)

            else:
                if dis[i]==dis[x]+j:
                    continue
                else:
                    print('No')
                    exit()
    return flag


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

for i in range(m):
    vec[a[i][0]-1].append((a[i][1]-1,a[i][2]))
    vec[a[i][1]-1].append((a[i][0]-1,-a[i][2]))

INF=float('inf')
dis=[INF]*n

for i in range(n):
    if dis[i]==INF:
        bfs(i)
print('Yes')
# Original solution
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])



def func():
    visited = [False for i in range(n)]
    x = [None for i in range(n)]
    for i in range(n):
        if visited[i] == False:
            q = [i]
        while q:
            j = q.pop()
            visited[j] = True
            if x[j] == None:
                x[j] = 0
            for k, d in graph[j]:
                if visited[k] == False:
                    q.append(k)
                if x[k] == None:
                    x[k] = x[j] + d
                elif x[k] != x[j] + d:
                    return False
    return True

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

# Optimized solution
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])



def func():
    x = [None for i in range(n)]
    for i in range(n):
        if x[i] == None:
            x[i] = 0
            q = [i]
        while q:
            j = q.pop()
            for k, d in graph[j]:
                if x[k] == None:
                    q.append(k)
                    x[k] = x[j] + d
                elif x[k] != x[j] + d:
                    return False
    return True

if func():
    print('Yes')
else:
    print('No')
# Original solution
N,M = list(map(int,input().split()))
info = [list(map(int,input().split())) for i in range(M)]
nodes = [i for i in range(N)]
rank = [0]*N
diff_weight = [0]*N

def root(x):
    if nodes[x] == x:
        return x
    root_x = root(nodes[x])
    diff_weight[x] += diff_weight[nodes[x]]
    nodes[x] = root_x
    return root_x

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

def unite(x,y,w):
    w += weight(x); w -= weight(y)
    x = root(x); y = root(y)
    if x == y:
        return
    if rank[x] >= rank[y]:
        nodes[y] = x
        diff_weight[y] = w
        if rank[x] == rank[y]:
            rank[x] += 1
    else:
        nodes[x] = y
        diff_weight[x] = -w

def same(x,y):
    return root(x) == root(y)

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

ans = "Yes"

for L,R,D in info:
    L -= 1; R -= 1
    unite(L,R,D)
    if diff(L,R) != D:
        ans = "No"
        break
print(ans)

# Optimized solution
N,M = list(map(int,input().split()))
info = [list(map(int,input().split())) for i in range(M)]
nodes = [-1]*N
diff_weight = [0]*N

def root(x):
    if nodes[x] < 0:
        return x
    root_x = root(nodes[x])
    diff_weight[x] += diff_weight[nodes[x]]
    nodes[x] = root_x
    return root_x

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

def unite(x,y,w):
    w += weight(x); w -= weight(y)
    x = root(x); y = root(y)
    if x == y:
        return
    rank_x = -nodes[x]; rank_y = -nodes[y]
    if rank_x >= rank_y:
        nodes[y] = x
        diff_weight[y] = w
        if rank_x == rank_y:
            nodes[x] -= 1
    else:
        nodes[x] = y
        diff_weight[x] = -w

def same(x,y):
    return root(x) == root(y)

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

ans = "Yes"

for L,R,D in info:
    L -= 1; R -= 1
    unite(L,R,D)
    if diff(L,R) != D:
        ans = "No"
        break
print(ans)
# Original solution
N,M = list(map(int,input().split()))
info = [list(map(int,input().split())) for i in range(M)]
nodes = [-1]*N
diff_weight = [0]*N

def root(x):
    if nodes[x] < 0:
        return x
    root_x = root(nodes[x])
    diff_weight[x] += diff_weight[nodes[x]]
    nodes[x] = root_x
    return root_x

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

def unite(x,y,w):
    w += weight(x); w -= weight(y)
    x = root(x); y = root(y)
    if x == y:
        return
    rank_x = -nodes[x]; rank_y = -nodes[y]
    if rank_x >= rank_y:
        nodes[y] = x
        diff_weight[y] = w
        if rank_x == rank_y:
            nodes[x] -= 1
    else:
        nodes[x] = y
        diff_weight[x] = -w

def same(x,y):
    return root(x) == root(y)

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

ans = "Yes"

for L,R,D in info:
    L -= 1; R -= 1
    unite(L,R,D)
    if diff(L,R) != D:
        ans = "No"
        break
print(ans)

# Optimized solution
def prepare(n):
    global nodes,diff_weight
    # ノードは-1で初期化, Nは頂点数
    nodes = [-1]*n
    # 差分重みは0で初期化, Nは頂点数
    diff_weight = [0]*n

# 差分重みの累積和をとることでxの重みが分かる
def weight(x):
    # xの重みを知りたいので経路圧縮
    root(x)
    return diff_weight[x]

# xからyへの重み
def diff(x,y):
    return weight(y) - weight(x)

# x,yの根が同じ->True
def same(x,y):
    return root(x) == root(y)

# xの木の高さを返す
def rank(x):
    return -nodes[x]

def root(x):
    # ノードが負 <=> xは根
    if nodes[x] < 0:
        return x
    else:
        # 再帰的に根を調べる
        root_x = root(nodes[x])
        # 根に近いものから親の重みを足す. これがxを根に直接繋いだ時の重みになる
        diff_weight[x] += diff_weight[nodes[x]]
        # xを根に直接繋ぎ直す
        nodes[x] = root_x
        return root_x

def unite(x,y,w):
    # 以下x,yの根について考えるので,重みを補正
    w += weight(x); w -= weight(y)
    x = root(x); y = root(y)
    # 根が同じならreturn (自己ループを考慮)
    if x == y:
        return
    rank_x = rank(x); rank_y = rank(y)
    # xの方が木が高いことを想定しているのでx,yをスワップ,wを-wに
    if rank_x < rank_y:
        x,y = y,x; w = -w
    # 木の高さが同じ場合は繋いだ後の高さが1だけ高くなる
    if rank_x == rank_y:
        nodes[x] -= 1
    # 低い木の根を高い木の根に繋ぎ直す
    nodes[y] = x
    # 低い木の根の差分重みを設定
    diff_weight[y] = w

N,M = list(map(int,input().split()))
prepare(N)
ans = "Yes"
for _ in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1; R -= 1
    unite(L,R,D)
    if diff(L,R) != D:
        ans = "No"
print(ans)
# Original solution
class Unionfind:
    __slots__ = ["nodes","diff_weight"]

    def __init__(self, n):
        self.nodes = [-1]*n
        self.diff_weight = [0]*n

    def root(self, x):
        if self.nodes[x] < 0:
            return x
        else:
            root_x = self.root(self.nodes[x])
            self.diff_weight[x] += self.diff_weight[self.nodes[x]]
            self.nodes[x] = root_x
            return root_x
    
    def unite(self, x, y, w=0):
        w += self.weight(x); w -= self.weight(y)
        x = self.root(x); y = self.root(y)
        if x == y:
            return
        rank_x = -self.nodes[x]; rank_y = -self.nodes[y]
        if rank_x < rank_y:
            x, y = y, x; w = -w
        if rank_x == rank_y:
            self.nodes[x] -= 1
        self.nodes[y] = x
        self.diff_weight[y] = w

    def weight(self, x):
        self.root(x)
        return self.diff_weight[x]
    
    def diff(self, x, y):
        return self.weight(y) - self.weight(x)
    
    def same(self, x, y):
        return self.root(x) == self.root(y)
    
    def rank(self, x):
        return -self.nodes[self.root(x)]
    
N,M = list(map(int,input().split()))
uf = Unionfind(N)
ans = "Yes"
for _ in range(M):
    L, R, D = list(map(int,input().split()))
    L -= 1; R -= 1
    uf.unite(L, R, D)
    if uf.diff(L, R) != D:
        ans = "No"
        break
print(ans)

# Optimized solution
import sys
input = sys.stdin.readline

class Unionfind:
    __slots__ = ["nodes","diff_weight"]

    def __init__(self, n):
        self.nodes = [-1]*n
        self.diff_weight = [0]*n

    def root(self, x):
        if self.nodes[x] < 0:
            return x
        else:
            root_x = self.root(self.nodes[x])
            self.diff_weight[x] += self.diff_weight[self.nodes[x]]
            self.nodes[x] = root_x
            return root_x
    
    def unite(self, x, y, w=0):
        w += self.weight(x); w -= self.weight(y)
        x = self.root(x); y = self.root(y)
        if x == y:
            return
        rank_x = -self.nodes[x]; rank_y = -self.nodes[y]
        if rank_x < rank_y:
            x, y = y, x; w = -w
        if rank_x == rank_y:
            self.nodes[x] -= 1
        self.nodes[y] = x
        self.diff_weight[y] = w

    def weight(self, x):
        self.root(x)
        return self.diff_weight[x]
    
    def diff(self, x, y):
        return self.weight(y) - self.weight(x)
    
    def same(self, x, y):
        return self.root(x) == self.root(y)
    
    def rank(self, x):
        return -self.nodes[self.root(x)]
    
N,M = list(map(int,input().split()))
uf = Unionfind(N)
ans = "Yes"
for _ in range(M):
    L, R, D = list(map(int,input().split()))
    L -= 1; R -= 1
    uf.unite(L, R, D)   
    if uf.diff(L, R) != D:
        ans = "No"
        break
print(ans)
# Original solution
import sys
input = sys.stdin.readline

class WeightedUnionfind:

    __slots__ = ['nodes','diff_weight']

    def __init__(self, n):
        self.nodes = [-1]*n
        self.diff_weight = [0]*n

    def root(self, x):
        if self.nodes[x] < 0:
            return x
        else:
            root_x = self.root(self.nodes[x])
            self.diff_weight[x] += self.diff_weight[self.nodes[x]]
            self.nodes[x] = root_x
            return root_x

    def unite(self, x, y, w=0):
        w += self.weight(x); w -= self.weight(y)
        x = self.root(x); y = self.root(y)
        if x == y:
            return
        rank_x = -self.nodes[x]; rank_y = -self.nodes[y]
        if rank_x < rank_y:
            x, y = y, x; w = -w
        if rank_x == rank_y:
            self.nodes[x] -= 1
        self.nodes[y] = x
        self.diff_weight[y] = w

    def weight(self, x):
        self.root(x)
        return self.diff_weight[x]

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

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

    def rank(self, x):
        return -self.nodes[self.root(x)]

N,M = list(map(int,input().split()))
info = [list(map(int,input().split())) for i in range(M)]
wuf = WeightedUnionfind(N+1)
ans = "Yes"
for L,R,D in info:
    if wuf.same(L,R):
        if wuf.diff(L,R) != D:
            ans = "No"
        else:
            pass
    else:
        wuf.unite(L,R,D)
print(ans)

# Optimized solution
import sys
input = sys.stdin.readline

class WeightedUnionfind:

    __slots__ = ['nodes','diff_weight']

    def __init__(self, n):
        self.nodes = [-1]*n
        self.diff_weight = [0]*n

    def root(self, x):
        if self.nodes[x] < 0:
            return x
        else:
            root_x = self.root(self.nodes[x])
            self.diff_weight[x] += self.diff_weight[self.nodes[x]]
            self.nodes[x] = root_x
            return root_x

    def unite(self, x, y, w=0):
        w += self.weight(x); w -= self.weight(y)
        x = self.root(x); y = self.root(y)
        if x == y:
            return
        size_x = -self.nodes[x]; size_y = -self.nodes[y]
        if size_x < size_y:
            x, y = y, x; w = -w
        self.nodes[x] += self.nodes[y]
        self.nodes[y] = x
        self.diff_weight[y] = w

    def weight(self, x):
        self.root(x)
        return self.diff_weight[x]

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

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

    def size(self, x):
        return -self.nodes[self.root(x)]

N,M = list(map(int,input().split()))
wuf = WeightedUnionfind(N)
ans = "Yes"
for _ in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1; R -= 1
    if not wuf.same(L,R):
        wuf.unite(L,R,D)
    else:
        if wuf.diff(L,R) != D:
            ans = "No"
            break
print(ans)
# Original solution
#PyPy遅え
import sys
sys.setrecursionlimit(400000000)
inf=1000000000000000000
n,m=list(map(int,input().split()))
x=[inf]*n
#まだ訪問してなければTrue
check=[True]*n
#どこと関係があるかを記録する(maybe right)
lrd=[[] for i in range(n)]
for i in range(m):
    l,r,d=list(map(int,input().split()))
    l-=1
    r-=1
    lrd[l].append((r,d))
    lrd[r].append((l,-d))
#wrong thought
#どっちも決まってない場合の処理
#決まってるとこからやれば良い
#ソートして順番に決めておく

#記録した関係から辿っていく
#まず初めのやつ決定
#非連結な場合を忘れていた

f=False
def bfs(z):
    #globalくらいちゃんとしろ
    global lrd,check,x,f
    if f:return
    for i in range(len(lrd[z])):
        k=lrd[z][i]
        if check[k[0]]:
            x[k[0]]=x[z]+k[1]
            check[k[0]]=False
            bfs(k[0])
        else:
            if x[k[0]]!=x[z]+k[1]:
                f=True
                return
st=0
while any(check):
    for i in range(st,n):
        if len(lrd[i])!=0 and check[i]:
            st=i
            break
        else:
            check[i]=False
    else:
        break
    x[st]=0
    check[st]=False
    bfs(st)
    #print(check)
if f:
    print("No")
else:
    print("Yes")

# Optimized solution
#PyPy遅え
import sys
sys.setrecursionlimit(100000000)
inf=1000000000000000000
n,m=list(map(int,input().split()))
x=[inf]*n
#まだ訪問してなければTrue
check=[True]*n
#どこと関係があるかを記録する(maybe right)
lrd=[[] for i in range(n)]
for i in range(m):
    l,r,d=list(map(int,input().split()))
    l-=1
    r-=1
    lrd[l].append((r,d))
    lrd[r].append((l,-d))
#wrong thought
#どっちも決まってない場合の処理
#決まってるとこからやれば良い
#ソートして順番に決めておく

#記録した関係から辿っていく
#まず初めのやつ
st=-1
for i in range(n):
    if len(lrd[i])>=1:
        st=i
        break

def bfs(z):
    #globalくらいちゃんとしろ
    global lrd,check,x
    for i in range(len(lrd[z])):
        k=lrd[z][i]
        if check[k[0]]:
            x[k[0]]=x[z]+k[1]
            check[k[0]]=False
            bfs(k[0])

st=0
while any(check):
    for i in range(st,n):
        if len(lrd[i])!=0 and check[i]:
            st=i
            break
        else:
            check[i]=False
    else:
        break
    x[st]=0
    check[st]=False
    bfs(st)

for i in range(n):
    l=len(lrd[i])
    for j in range(l):
        k=lrd[i][j]
        if x[k[0]]!=x[i]+k[1]:
            print("No")
            sys.exit()
print("Yes")
# Original solution
N, M = list(map(int, input().split()))

e_IN = [[] for _ in range(N+1)]
e_OUT = [[] for _ in range(N+1)]

for _ in range(M):
    l, r, d = list(map(int, input().split()))
    e_OUT[l].append((r, d))
    e_IN[r].append((l, d))

posx = [-1] * (N + 1)


def dfs(v):
    #　0<=x<=10**9に注意
    node = [v]
    posx[v] = 0
    diameter = 0
    while node:
        s = node.pop()
        ds = posx[s]
        for t, dt in e_OUT[s]:
            dist = ds + dt
            if posx[t] != -1:
                if posx[t] != dist:
                    return False
                else:
                    continue
            posx[t] = dist
            node.append(t)
            diameter = max(diameter, dist)
    if diameter <= 10 ** 9:
        return True
    else:
        return False


ans = "Yes"
for i in range(N + 1):
    if len(e_IN[i]) == 0:
        posx[i] = 0
        bl = dfs(i)
        if not bl:
            ans = "No"
            break

if - 1 in posx:
    ans = "No"

print(ans)


# Optimized solution
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10 ** 7)

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

e_IN = [[] for _ in range(N+1)]
e_OUT = [[] for _ in range(N+1)]

for _ in range(M):
    l, r, d = list(map(int, readline().split()))
    e_OUT[l].append((r, d))
    e_IN[r].append((l, d))

posx = [-1] * (N + 1)


def dfs(v):
    #　0<=x<=10**9に注意
    node = [v]
    posx[v] = 0
    diameter = 0
    while node:
        s = node.pop()
        ds = posx[s]
        for t, dt in e_OUT[s]:
            dist = ds + dt
            if posx[t] != -1:
                if posx[t] != dist:
                    return False
                else:
                    continue
            posx[t] = dist
            node.append(t)
            diameter = max(diameter, dist)
    if diameter <= 10 ** 9:
        return True
    else:
        return False


ans = "Yes"
for i in range(N + 1):
    if len(e_IN[i]) == 0:
        posx[i] = 0
        bl = dfs(i)
        if not bl:
            ans = "No"
            break

if - 1 in posx:
    ans = "No"

print(ans)