CodeEff/ECCO huggingface dataset:
# Original solution
import sys
sys.setrecursionlimit(2147483647)
INF=float('inf')
MOD=10**9+7
input=sys.stdin.readline

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

#初期値が0の辞書
from collections import defaultdict
lrd = defaultdict(lambda: []) 

yx=[[0]*n for _ in range(n)]

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



def BFD(x):
    global checked,answer
    checked[x]=1
    #print("x>>>",x)
    for item in lrd[x]:
        #print(lrd,item,x)
        ll=min(item,x)
        rr=max(item,x)
        if answer[item]==-1:
            if item<=x:
                answer[item]=answer[x]-yx[item][x]
            else:
                answer[item]=answer[x]+yx[x][item]
        else:
            if answer[rr]!=answer[ll]+yx[ll][rr]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n

for i in range(n):
    if checked[i]==0:
        answer = defaultdict(lambda: -1) 
        answer[i]=1
        BFD(i)

print("Yes")


# Optimized solution
import sys
sys.setrecursionlimit(2147483647)
INF=float('inf')
MOD=10**9+7
input=sys.stdin.readline

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

#初期値が0の辞書
from collections import defaultdict
lrd = defaultdict(lambda: []) 

lr=defaultdict(lambda: 0) 

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

def BFD(x):
    global checked,answer,lrd
    checked[x]=1
    #print("x>>>",x)
    for llrrdd in lrd[x]:
        #print(lrd,item,x)
        item=llrrdd[0]
        if answer[item]==INF:
            answer[item]=answer[x]-llrrdd[1]
        else:
            if answer[item]!=answer[x]-llrrdd[1]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n

for i in range(n):
    if checked[i]==0:
        answer = defaultdict(lambda: INF) 
        answer[i]=1
        BFD(i)

print("Yes")
# Original solution
import sys
sys.setrecursionlimit(2147483647)
INF=10**10
MOD=10**9+7
input=sys.stdin.readline

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

#初期値が0の辞書
from collections import defaultdict
lrd = defaultdict(lambda: []) 

lr=defaultdict(lambda: 0) 

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

def BFD(x):
    global checked,answer,lrd
    checked[x]=1
    #print("x>>>",x)
    for llrrdd in lrd[x]:
        #print(lrd,item,x)
        item=llrrdd[0]
        if answer[item]==INF:
            answer[item]=answer[x]-llrrdd[1]
        else:
            if answer[item]!=answer[x]-llrrdd[1]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n

for i in range(n):
    if checked[i]==0:
        answer = defaultdict(lambda: INF) 
        answer[i]=1
        BFD(i)

print("Yes")


# Optimized solution
import sys
sys.setrecursionlimit(2147483647)
INF=10**10
MOD=10**9+7
input=sys.stdin.readline

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

#初期値が0の辞書
#from collections import defaultdict
#lrd = defaultdict(lambda: []) 

lrd=[[] for _ in range(n)]

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

#print(lrd)

def BFD(x):
    global checked,answer,lrd
    checked[x]=1
    #print("x>>>",x,lrd[x])
    for llrrdd in lrd[x]:
        #print(llrrdd,x)
        item=llrrdd[0]
        if answer[item]==-10**10:
            answer[item]=answer[x]-llrrdd[1]
        else:
            if answer[item]!=answer[x]-llrrdd[1]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n

for i in range(n):
    if checked[i]==0:
        answer = [-10**10]*n
        answer[i]=1
        BFD(i)

print("Yes")
# Original solution
import sys
sys.setrecursionlimit(2147483647)
INF=10**10
MOD=10**9+7
input=sys.stdin.readline

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

#初期値が0の辞書
#from collections import defaultdict
#lrd = defaultdict(lambda: []) 

lrd=[[] for _ in range(n)]

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

#print(lrd)

def BFD(x):
    global checked,answer,lrd
    checked[x]=1
    #print("x>>>",x,lrd[x])
    for llrrdd in lrd[x]:
        #print(llrrdd,x)
        item=llrrdd[0]
        if answer[item]==-10**10:
            answer[item]=answer[x]-llrrdd[1]
        else:
            if answer[item]!=answer[x]-llrrdd[1]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n

for i in range(n):
    if checked[i]==0:
        answer = [-10**10]*n
        answer[i]=1
        BFD(i)

print("Yes")


# Optimized solution
import sys
sys.setrecursionlimit(100000)
input=sys.stdin.readline

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

lrd=[[] for _ in range(n)]

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

#print(lrd)

def BFD(x):
    global checked,answer,lrd
    checked[x]=1
    #print("x>>>",x,lrd[x])
    for llrrdd in lrd[x]:
        #print(llrrdd,x)
        item=llrrdd[0]
        if answer[item]=="first":
            answer[item]=answer[x]-llrrdd[1]
        else:
            if answer[item]!=answer[x]-llrrdd[1]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n

for i in range(n):
    if checked[i]==0:
        answer = ["first"]*n
        answer[i]=1
        BFD(i)

print("Yes")
# Original solution
import sys
sys.setrecursionlimit(100000)
input=sys.stdin.readline

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

lrd=[[] for _ in range(n)]

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

#print(lrd)

def BFD(x):
    global checked,answer,lrd
    checked[x]=1
    #print("x>>>",x,lrd[x])
    for llrrdd in lrd[x]:
        #print(llrrdd,x)
        item=llrrdd[0]
        if answer[item]=="first":
            answer[item]=answer[x]-llrrdd[1]
        else:
            if answer[item]!=answer[x]-llrrdd[1]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n

for i in range(n):
    if checked[i]==0:
        answer = ["first"]*n
        answer[i]=1
        BFD(i)

print("Yes")


# Optimized solution
import sys
sys.setrecursionlimit(100000)
input=sys.stdin.readline

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

lrd=[[] for _ in range(n)]

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

def BFD(x):
    global checked,answer,lrd
    checked[x]=1
    #print("x>>>",x,lrd[x])
    for llrrdd in lrd[x]:
        #print(llrrdd,x)
        item=llrrdd[0]
        if answer[item]=="first":
            answer[item]=answer[x]-llrrdd[1]
        else:
            if answer[item]!=answer[x]-llrrdd[1]:
                print("No")
                exit()
        if checked[item]==0:
            BFD(item)

checked=[0]*n
answer = ["first"]*n

for i in range(n):
    if checked[i]==0:
        answer[i]=1
        BFD(i)

print("Yes")
# Original solution
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
for i in range(n):
    if not flag: break
    dist = [10**10]*n
    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')


# Optimized solution
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')
# Original solution
import sys
from collections import deque

def solve():
    input = sys.stdin.readline
    N, M = list(map(int, input().split()))
    Edge = [[] for _ in range(N)]
    for _ in range(M):
        l, r, d = list(map(int, input().split()))
        Edge[l-1].append((r-1, d))
        Edge[r-1].append((l-1, -1 * d))
    Dist = [10 ** 20] * N
    possible = True
    for i in range(N):
        if Dist[i] == 10 ** 20:
            q = deque()
            q.append((i, 0))
            while q:
                nn, nd = q.popleft()
                if Dist[nn] == 10 ** 20:
                    Dist[nn] = nd
                    for ne, add in Edge[nn]: q.append((ne, nd + add))
                else:
                    if Dist[nn] == nd: continue
                    else:
                        possible = False
                        break
            if not possible:
                print("No")
                break
    else: print("Yes")

    return 0

if __name__ == "__main__":
    solve()

# Optimized solution
import sys
from collections import deque

def solve():
    input = sys.stdin.readline
    N, M = list(map(int, input().split()))
    E = [[] for _ in range(N)]
    for _ 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))
    Pos = [10 ** 20] * N
    q = deque()
    flag = True
    for i in range(N):
        if Pos[i] == 10 ** 20:
            q.append((i, 0))
            minX, maxX = 0, 0
            while q:
                x, p = q.popleft()
                if Pos[x] == 10 ** 20:
                    minX = min(minX, p)
                    maxX = max(maxX, p)
                    Pos[x] = p
                    for ne, d in E[x]: q.append((ne, p + d))
                elif Pos[x] == p: continue
                else:
                    flag = False
                    break
            else:
                if maxX - minX <= 10 ** 9: continue
                else: flag = False
            if not flag:
                print("No")
                break
    else: print("Yes")
    #print(Pos)
            
    return 0

if __name__ == "__main__":
    solve()
# Original solution
import sys
input = sys.stdin.readline

n, m = [int(x) for x in input().split()]
g = [[] for _ in range(n)]

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

d = [0] * n
from collections import deque

queue = deque([])

for i in range(n):
    if d[i] != 0:
        continue
    queue.append(i)
    while queue:
        u = queue.popleft()
        for v, d_ in g[u]:
            if d[v] == 0 and v != i:
                d[v] = d[u] + d_
                queue.append(v)
            else:
                if d[v] != d[u] + d_:
                    print("No")
                    sys.exit()
    d[i] = 1
print("Yes")


# Optimized solution
n, m = list(map(int, input().split()))
ed = [[] for _ in range(n)]  # グラフ
v = [None] * n
for _ in range(m):
  l, r, d = list(map(int, input().split()))
  ed[l-1].append((r-1, d))  # l -> r
  ed[r-1].append((l-1, -d))  # r -> l

visited = [False] * n  # 訪問フラグ（非連結の可能性の為）

def dfs(start):
  s = [start]
  v[start] = 0
  while s:
    label = s.pop()
    if visited[label] == False:
      visited[label] = True
      for to, dist in ed[label]:
        if v[to] is None:
          v[to] = v[label] + dist
          s.append(to)
        else:
          if v[to] != v[label] + dist:
            return False
  return True

is_exist = True
for i in range(n):
  if v[i] is None:
    if not dfs(i):
      print('No')
      is_exist = False
      break
if is_exist:
  print("Yes")
# Original solution
import sys
input = sys.stdin.readline

n, m = [int(x) for x in input().split()]
g = [[] for _ in range(n)]

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

d = [0] * n
visited = [0] * n

for i in range(n):
    if visited[i] != 0:
        continue
    stack = [i]
    d[i] = 1
    while stack:
        u = stack.pop()
        visited[u] = 1
        for v, d_ in g[u]:
            if d[v] == 0:
                d[v] = d[u] + d_
                stack.append(v)
            else:
                if d[v] != d[u] + d_:
                    print("No")
                    sys.exit()
print("Yes")


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

n, m = [int(x) for x in input().split()]
g = [[] for _ in range(n)]

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

d = [None] * n
visited = [0] * n

for i in range(n):
    if visited[i] != 0:
        continue
    stack = [i]
    d[i] = 1
    while stack:
        u = stack.pop()
        visited[u] = 1
        for v, d_ in g[u]:
            if d[v] is None:
                d[v] = d[u] + d_
                stack.append(v)
            else:
                if d[v] != d[u] + d_:
                    print("No")
                    sys.exit()
print("Yes")
# Original solution
import sys
sys.setrecursionlimit(100000)

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

graph = [{} for _ in range(N)]
for l, r, d in LRD:
	l, r = l - 1, r - 1
	graph[l][r] = d
	graph[r][l] = -d

visited = [False] * N
def dfs(v, p, d, depths):
	if visited[v]:
		return True
	visited[v] = True

	if depths[v] != -1:
		return True
	depths[v] = d

	for n in graph[v]:
		if n == p:
			continue
		n_depth = d + graph[v][n]
		if depths[n] != -1 and depths[n] != n_depth:
			return False
		result = dfs(n, v, n_depth, depths)
		if not result:
			return False
	return True

for n in range(N):
	if not dfs(n, -1, 0, [-1] * N):
		print("No")
		break
else:
	print("Yes")


# Optimized solution
import sys
sys.setrecursionlimit(100000)

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

graph = [{} for _ in range(N)]
for l, r, d in LRD:
	l, r = l - 1, r - 1
	graph[l][r] = d
	graph[r][l] = -d

visited = [False] * N
depths = [-1] * N
def dfs(v, p, d):
	if visited[v]:
		return True
	visited[v] = True
	depths[v] = d

	for n in graph[v]:
		if n == p:
			continue
		n_depth = d + graph[v][n]
		if depths[n] != -1 and depths[n] != n_depth:
			return False
		result = dfs(n, v, n_depth)
		if not result:
			return False
	return True

for n in range(N):
	if not dfs(n, -1, 0):
		print("No")
		break
else:
	print("Yes")
# Original solution
import sys
sys.setrecursionlimit(100000)

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

graph = [{} for _ in range(N)]
for l, r, d in LRD:
	l, r = l - 1, r - 1
	graph[l][r] = d
	graph[r][l] = -d

visited = [False] * N
depths = [-1] * N
def dfs(v, p, d):
	if visited[v]:
		return True
	visited[v] = True
	depths[v] = d

	for n in graph[v]:
		if n == p:
			continue
		n_depth = d + graph[v][n]
		if depths[n] != -1 and depths[n] != n_depth:
			return False
		result = dfs(n, v, n_depth)
		if not result:
			return False
	return True

for n in range(N):
	if not dfs(n, -1, 0):
		print("No")
		break
else:
	print("Yes")


# Optimized solution
import sys
sys.setrecursionlimit(100000)

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

graph = [{} for _ in range(N)]
for l, r, d in LRD:
	l, r = l - 1, r - 1
	graph[l][r] = d
	graph[r][l] = -d

visited = [False] * N
depths = [0] * N
def dfs(v):
	q = [v]
	while q:
		cu = q.pop()
		for nx, d in list(graph[cu].items()):
			if visited[nx]:
				if depths[nx] != depths[cu] + d:
					return False
			else:
				visited[nx] = True
				depths[nx] = depths[cu] + d
				q += [nx]
	return True

for n in range(N):
	if not visited[n]:
		if not dfs(n):
			print("No")
			break
else:
	print("Yes")
# Original solution
# coding=utf-8

line = input().split(" ")
N = int(line[0])
M = int(line[1])

if M==0:
    print("Yes")
    exit()

l = []
for _ in range(M):
    line = input().split(" ")
    l.append((
        int(line[0])-1
        ,int(line[1])-1
        ,int(line[2])
    ))
l.sort()
o = l[0][0]
for i in range(M):
    l[i] = (
        l[i][0]-o
        ,l[i][1]-o
        ,l[i][2]
    )

nl = [-1 for x in range(N)]
nl[0] = 0

flag = True
while flag:
    flag = False
    ll = []
    for c in l:
        if nl[c[0]]>=0 and nl[c[1]]==-1:
            nl[c[1]] = nl[c[0]]+c[2]
        elif nl[c[0]]==-1 and nl[c[1]]>=0:
            nl[c[0]] = nl[c[1]]-c[2]
        elif nl[c[0]]>=0 and nl[c[1]]>=0:
            if nl[c[1]]-nl[c[0]]==c[2]:
                pass
            else:
                print("No")
                exit()
        else:
            ll.append(c)
            flag = True
    l = ll.copy()

print("Yes")


# Optimized solution
# -*- coding: utf-8 -*-

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 unite(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 = list(map(int, input().split()))
uf = WeightedUnionFind(n)
for _ in range(m):
    l,r,d = list(map(int, input().split()))
    if uf.same(l,r):
        if uf.diff(l,r) != d:
            print("No")
            exit()
    else:
        uf.unite(l,r,d)

print("Yes")
# Original solution
from collections import deque
from collections import defaultdict

N,M=list(map(int,input().split()))
nl=[ [] for i in range(N+1) ]
cost={}

for i in range(M):
	L,R,D=list(map(int,input().split()))
	if i==0:start=L
	nl[L].append(R)
	nl[R].append(L)
	cost[(L,R)]=D
	cost[(R,L)]=-D


d=[ None for i in range(N+1) ]
V=[ 0 for i in range(N+1) ]
V2=[]

def dfs(start):
	q = deque([]) 
	V[start]=1
	d[start]=0
	q.append(start)

	while len(q)!=0:
		v=q.pop()
		for i in nl[v]:
			if V[i]!=1:
				V[i]=1
				V2.append((v,i))
				q.append(i)
				d[i]=d[v]+cost[(v,i)]
			
			if (v,i) not in V2:
				if d[v]-d[i]!=cost[(i,v)]:
					print("No")
					quit()

for i in range(1,N+1):
	if V[i]==0:
		dfs(i)
else:
	print("Yes")




# Optimized solution
from collections import deque
from collections import defaultdict

N,M=list(map(int,input().split()))
nl=[ [] for i in range(N+1) ]
cost={}

for i in range(M):
	L,R,D=list(map(int,input().split()))
	if i==0:start=L
	nl[L].append(R)
	nl[R].append(L)
	cost[(L,R)]=D
	cost[(R,L)]=-D


d=[ None for i in range(N+1) ]
V=[ 0 for i in range(N+1) ]

def dfs(start):
	q = deque([]) 
	V[start]=1
	d[start]=0
	q.append(start)

	while len(q)!=0:
		v=q.pop()
		for i in nl[v]:
			if V[i]!=1:
				V[i]=1
				q.append(i)
				d[i]=d[v]+cost[(v,i)]
			else:
				if d[i]-d[v]!=cost[(v,i)]:
					print("No")
					quit()

for i in range(1,N+1):
	if V[i]==0:
		dfs(i)
else:
	print("Yes")
# Original solution
N, M = list(map(int,input().split()))
L = [0] * M
R = [0] * M
D = [0] * M
for i in range(M):
	L[i],R[i],D[i] = list(map(int,input().split()))
#	print(L[i],R[i],D[i])
leftside = 0
cand = set()
for i in range(M):
	cand.add(L[i])
for i in range(M):
	if R[i] in cand:
		cand.remove(R[i])

res = True
if M == 0:
	res = True
else:
	if len(cand) == 0:
		res = False
	else:
		leftside = list(cand)
#		print("leftside:",leftside)
		ok = True
		for c in leftside:
			point = [-1] * (N+1)
			point[c] = 0
			ok = True
			while True:
				update = False
				for i in range(M):
					if point[L[i]] != -1:
						if point[R[i]] == -1:
							update = True
							point[R[i]] = point[L[i]] + D[i]
						else:
							if point[R[i]] != point[L[i]] + D[i]:
								ok = False
								break
				if update == False:
					break
				res &= ok
					
print(("Yes" if res == True else "No"))

# Optimized solution
NOT_VISIT = 10**20
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))

visited = [NOT_VISIT for i in range(N)]

def dfs(start):
	global graph, visited

	if visited[start] != NOT_VISIT:
		return True

	stack = [start]
	visited[start] = 0
	while stack:
		label = stack.pop()
		for nextnode, distance in graph[label]:
			if visited[nextnode] == NOT_VISIT:
				stack.append(nextnode)
				visited[nextnode] = visited[label] + distance
			elif visited[nextnode] != visited[label] + distance:
				return False
	return True

res = True
for i in range(N):
	res &= dfs(i)

print(("Yes" if res == True else "No"))
# Original solution
import sys
sys.setrecursionlimit(100000000)
N,M = list(map(int,input().split()))
e = [[] for i in range(N)]
t = 0
a = []
for i in range(M):
    r,l,d = list(map(int,input().split()))
    e[r-1].append([l-1,d])
    e[l-1].append([r-1,-d])
    a.append(r-1)
    a.append(l-1)
    t = r-1

col = [ float("inf") for i in range(N) ]
def dfs(i,c):

    for node in e[i]:
        if col[node[0]] == float("inf"):
            col[node[0]] = c + node[1]
            dfs(node[0],c+node[1])
        elif col[node[0]] != c + node[1]:
            print("No")
            exit()


dfs(t,0)
a = list(set(a))
for i in a:
    if col[i] == float("inf"):
        dfs(i,0)


print("Yes")


# Optimized solution
import sys
sys.setrecursionlimit(100000000)

def main():
    N,M = list(map(int,input().split()))
    e = [[] for i in range(N)]
    t = 0
    a = []
    for i in range(M):
        r,l,d = list(map(int,input().split()))
        e[r-1].append([l-1,d])
        e[l-1].append([r-1,-d])
        a.append(r-1)
        a.append(l-1)
        t = r-1

    col = [ float("inf") for i in range(N) ]
    def dfs(i,c):

        for node in e[i]:
            if col[node[0]] == float("inf"):
                col[node[0]] = c + node[1]
                dfs(node[0],c+node[1])
            elif col[node[0]] != c + node[1]:
                print("No")
                exit()


    dfs(t,0)
    a = list(set(a))
    for i in a:
        if col[i] == float("inf"):
            dfs(i,0)


    print("Yes")


if __name__ == '__main__':
    main()