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

Source: atcoder | Difficulty: MEDIUM_HARD


Solutions:
import sys
import math
import collections
import bisect
import itertools
sys.setrecursionlimit(10 ** 7)
INF = 10 ** 16
MOD = 10 ** 9 + 7
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()])

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)
		if self.rank[rx] < self.rank[ry]:
			self.parents[rx] = ry
			self.weight[rx] = w - self.weight[x] + self.weight[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)

	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 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
	elif 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]
			elif 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()]]
	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')


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

def find(x):
	if par[x] < 0:
		return x
	else:
		px = find(par[x])
		wei[x] += wei[par[x]]
		par[x] = px
		return px

def weight(x):
	find(x)
	return wei[x]

def unite(x, y, w):
	w += wei[x] - wei[y]
	x = find(x)
	y = find(y)
	if x == y:
		return False
	else:
		if par[x] > par[y]:
			(x, y) = (y, x)
			w = -w
		par[x] += par[y]
		par[y] = x
		wei[y] = w
		return True

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

def size(x):
	return -par[find(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')


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')


(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])
			elif 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
INF = 10 ** 9
eps = 10 ** (-7)
(N, M) = list(map(int, input().split()))
par = [i for i in range(N + 1)]
rank = [0] * (N + 1)

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

def unite(x, y):
	x = root(x)
	y = root(y)
	if x == y:
		return
	if rank[x] < rank[y]:
		par[x] = y
	else:
		par[y] = x
		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():
	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
		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')


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) = 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')


(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]:
				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
	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
		for (r, nd) in edges[l]:
			q.append((r, c + nd))
print('Yes')


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')


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()
	if wuf.same(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])
			elif visited_cost[ni] != cost + nd:
				ng = True
				break
		if ng:
			break
	if ng:
		break
print('No' if ng else 'Yes')


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)
	elif 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)
			elif 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
for root in range(N):
	if root in seen:
		continue
	seen.add(root)
	V = [root]
	while len(V) != 0:
		v = V.pop(0)
		for (nv, d) in Graph[v]:
			if nv in seen and Dfr[nv] != Dfr[v] + d:
				print('No')
				return
			if nv in seen:
				continue
			else:
				seen.add(nv)
				Dfr[nv] = Dfr[v] + d
				V.append(nv)
print('Yes')


class PotentialUnionFind:

	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

	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)

	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')


(n, m) = list(map(int, input().split()))
info = [list(map(int, input().split())) for i in range(m)]
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)
			elif 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_)
			elif 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):
	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_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')


(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')


import sys
YES = 'Yes'
NO = 'No'

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

def main():

	def iterate_tokens():
		for line in sys.stdin:
			for word in line.split():
				yield word
	tokens = iterate_tokens()
	N = int(next(tokens))
	M = int(next(tokens))
	L = [int()] * M
	R = [int()] * M
	D = [int()] * M
	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

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]]
		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)

	def merge(self, x: int, y: int, w: int):
		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():
	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:

	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
			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
					elif 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()


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')


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

	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()


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])

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
		elif 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):

	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')


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)
			elif 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))
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')


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):

	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]]:
						e[g[2]] = 1
						if not visit[g[0]]:
							x[g[0]] = g[1] + x[j]
							visit[g[0]] = 1
							q.append(g[0])
						elif 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
					elif 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()


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))
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:
			print('No')
			return
		for (nxt, dis) in E[now]:
			if nxt == prev:
				continue
			if A[nxt] < INF and A[nxt] != num + dis:
				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')


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)
				elif 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)
		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())
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)
			elif t[k] != t[j] + l:
				print('No')
				return
print('Yes')