AtCoder Regular Contest 090 - People on a Line

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

Examples

Input

3 3
1 2 1
2 3 1
1 3 2


Output

Yes


Input

3 3
1 2 1
2 3 1
1 3 5


Output

No


Input

4 3
2 1 1
2 3 5
3 4 2


Output

Yes


Input

10 3
8 7 100
7 9 100
9 8 100


Output

No


Input

100 0


Output

Yes

Source: atcoder | Difficulty: UNKNOWN_DIFFICULTY


Solutions:
def inpl():
	return [int(i) for i in input().split()]

def find(x):
	if par[x] == x:
		return x
	else:
		(par[x], dist[x]) = (find(par[x]), dist[x] + dist[par[x]])
		return par[x]
(N, M) = inpl()
par = list(range(N + 1))
dist = [0 for _ in range(N + 1)]
for _ in range(M):
	(l, r, d) = inpl()
	fl = find(l)
	fr = find(r)
	if fl != fr:
		par[fr] = fl
		dist[fr] = d + dist[l] - dist[r]
	elif d + dist[l] - dist[r] != 0:
		print('No')
		break
else:
	print('Yes')


import sys
sys.setrecursionlimit(100000)

def check(i, xs, checked):
	xi = xs[i]
	children = set()
	for (j, d) in links[i]:
		if checked[j]:
			continue
		if j not in xs:
			xs[j] = xi + d
		elif xi + d != xs[j]:
			return False
		children.add(j)
	checked[i] = True
	for j in children:
		if not check(j, xs, checked):
			return False
	return True

def solve():
	checked = [False] * n
	for i in range(n):
		if not checked[i]:
			xs = {}
			xs[i] = 0
			res = check(i, xs, checked)
			if not res:
				return False
			(mn, mx) = (min(xs.values()), max(xs.values()))
			if mx - mn > 1000000000.0:
				return False
	return True
(n, m) = map(int, input().split())
links = [set() for _ in range(n)]
for _ in range(m):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	links[l].add((r, d))
	links[r].add((l, -d))
print('Yes' if solve() else 'No')


from sys import exit, setrecursionlimit
from functools import reduce
from itertools import *
from collections import defaultdict
from bisect import bisect
setrecursionlimit(1000000)
(N, M) = list(map(int, input().split()))
edges = [[] for _ in range(N)]
for i in range(M):
	(L, R, D) = list(map(int, input().split()))
	edges[L - 1].append((R - 1, D))
	edges[R - 1].append((L - 1, -D))
visited = [None] * N
place = [0] * N
inf = 10 ** 10

def walk(i):
	if visited[i]:
		return (place[i], place[i])
	visited[i] = True
	(n, m) = (inf, -inf)
	for (j, d) in edges[i]:
		if visited[j] and place[j] != place[i] + d:
			print('No')
			exit()
		place[j] = place[i] + d
		(x, y) = walk(j)
		(n, m) = (min(n, x), max(m, y))
	return (n, m)
for i in range(N):
	if not visited[i]:
		place[i] = 0
		(n, m) = walk(i)
		if m - n > 10 ** 9:
			print('No')
			exit()
print('Yes')


import sys
sys.setrecursionlimit(100000)
(N, M) = map(int, input().split())
union = list(range(N + 1))
dist = [0] * (N + 1)
rec = [0] * (N + 1)

def ascend(anc):
	count = 0
	while anc != union[anc]:
		rec[count] = anc
		anc = union[anc]
		count += 1
	rec[count] = anc
	for i in range(count - 1, -1, -1):
		dist[rec[i]] += dist[rec[i + 1]]
		union[rec[i]] = anc
	return anc

def connect(l, r, d):
	l_anc = ascend(l)
	r_anc = ascend(r)
	if l_anc != r_anc:
		union[l_anc] = r_anc
		dist[l_anc] = dist[r] + d - dist[l]

def is_union(l, r):
	return ascend(l) == ascend(r)

def check(l, r, d):
	return dist[r] + d == dist[l]
for i in range(M):
	(l, r, d) = map(int, input().split())
	if is_union(l, r):
		if not check(l, r, d):
			print('No')
			break
	else:
		connect(l, r, d)
else:
	print('Yes')


class WeightedUnionFind:

	def __init__(self, n):
		self.parents = [i for i in range(n + 1)]
		self.weights = [0 for _ in range(n + 1)]
		self.ranks = [0 for _ in range(n + 1)]

	def find_root(self, node):
		parent_node = self.parents[node]
		if node == parent_node:
			return node
		else:
			root_node = self.find_root(parent_node)
			self.parents[node] = root_node
			self.weights[node] += self.weights[parent_node]
			return root_node

	def union(self, one, other, weight):
		one_root = self.find_root(one)
		other_root = self.find_root(other)
		if one_root == other_root:
			return
		one_rank = self.ranks[one_root]
		other_rank = self.ranks[other_root]
		diff_weight = weight + self.weights[one] - self.weights[other]
		if one_rank < other_rank:
			self.parents[one_root] = other_root
			self.weights[one_root] -= diff_weight
		else:
			self.parents[other_root] = one_root
			self.weights[other_root] += diff_weight
			if one_rank == other_rank:
				self.ranks[other_root] += 1

	def is_same_group(self, one, other):
		one_root = self.find_root(one)
		other_root = self.find_root(other)
		return one_root == other_root

	def diff(self, one, other):
		if not self.is_same_group(one, other):
			return None
		return self.weights[other] - self.weights[one]

def main():
	(N, M) = list(map(int, input().split(' ')))
	tree = WeightedUnionFind(N)
	for _ in range(M):
		(L, R, D) = list(map(int, input().split(' ')))
		d = tree.diff(L, R)
		if d is None:
			tree.union(L, R, D)
			continue
		if d != D:
			print('No')
			exit(0)
	print('Yes')
main()


(N, M) = map(int, input().split())
es = [[] for i in range(N)]
for i in range(M):
	(l, r, d) = map(int, input().split())
	(l, r) = (l - 1, r - 1)
	es[l].append((r, d))
	es[r].append((l, -d))
dist = [None] * N
for i in range(N):
	if dist[i] is not None:
		continue
	dist[i] = 0
	stack = [i]
	while stack:
		v = stack.pop()
		for (to, d) in es[v]:
			if dist[to] is None:
				dist[to] = dist[v] + d
				stack.append(to)
			elif dist[to] != dist[v] + d:
				print('No')
				exit()
print('Yes')


(n, m) = map(int, input().split())
lrds = [tuple(map(int, input().split())) for _ in range(m)]
xs = [None for _ in range(n)]
ps = [[] for _ in range(n)]
for lrd in lrds:
	(l, r, d) = lrd
	ps[l - 1].append((r - 1, d))
	ps[r - 1].append((l - 1, -d))
not_decided = set(range(n))

def solve():
	while len(not_decided) != 0:
		t = not_decided.pop()
		xs[t] = 0
		stack = [t]
		while len(stack) != 0:
			c = stack.pop()
			for p in ps[c]:
				(another, relative_position) = p
				if another in not_decided:
					xs[another] = xs[c] + relative_position
					not_decided.remove(another)
					stack.append(another)
				elif xs[another] != xs[c] + relative_position:
					return False
	return True
if solve():
	print('Yes')
else:
	print('No')


def resolve():
	(N, M) = map(int, input().split())
	root = list(range(N))
	depth = [1 for _ in range(N)]
	dist = [0 for _ in range(N)]

	def find(a, root, dist):
		if root[a] == a:
			return (a, 0)
		else:
			(root[a], d) = find(root[a], root, dist)
			dist[a] += d
			return (root[a], dist[a])

	def unite(a, b, d, root, depth, dist):
		(A, dist_a) = find(a, root, dist)
		(B, dist_b) = find(b, root, dist)
		if A == B:
			if dist_b - dist_a == d:
				return True
			else:
				return False
		else:
			if depth[A] > depth[B]:
				root[B] = A
				depth[A] += depth[B]
				dist[B] = dist_a - dist_b + d
			else:
				root[A] = B
				depth[B] += depth[A]
				dist[A] = dist_b - dist_a - d
			return True
	ans = True
	for _ in range(M):
		(L, R, D) = map(int, input().split())
		if not unite(L - 1, R - 1, D, root, depth, dist):
			ans = False
			break
	print('Yes' if ans else 'No')
resolve()


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]
import sys
input = sys.stdin.readline
(N, M) = map(int, input().split())
uf = WeightedUnionFind(N)
for i in range(0, M):
	(l, r, d) = map(int, input().split())
	if uf.same(l, r):
		if d != uf.diff(l, r):
			print('No')
			break
	else:
		uf.union(l, r, d)
else:
	print('Yes')


(N, M) = [int(_) for _ in input().split()]
LRD = [[int(_) for _ in input().split()] for _ in range(M)]
G = {}
for (l, r, d) in LRD:
	l -= 1
	r -= 1
	G[l] = G.get(l, {})
	G[r] = G.get(r, {})
	G[l][r] = d
	G[r][l] = -d
INF = float('inf')
D = [INF] * N
for i in range(N):
	if i in G and D[i] == INF:
		D[i] = 0
		table = []
		while True:
			for (k, v) in G[i].items():
				if D[k] == INF:
					table += [k]
					D[k] = D[i] + v
				elif D[k] != D[i] + v:
					print('No')
					exit()
			if table:
				i = table.pop()
			else:
				break
print('Yes')


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

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]
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 uf.diff(l, r) != d:
			print('No')
			exit()
	else:
		uf.union(l, r, d)
print('Yes')


import sys
input = sys.stdin.readline
sys.setrecursionlimit(1000000)
from collections import deque, Counter

def getN():
	return int(input())

def getList():
	return list(map(int, input().split()))
import math
INF = 10 ** 10

def bfs(graph, visited, position, root):
	visited[root] = 1
	position[root] = 0
	deq = deque([root])
	while deq:
		cur = deq.pop()
		for (nxt, dist) in graph[cur]:
			if position[cur] + dist != position[nxt]:
				if position[nxt] != INF:
					return False
				else:
					position[nxt] = position[cur] + dist
			if not visited[nxt]:
				deq.append(nxt)
				visited[nxt] = 1
	return True

def main():
	(n, m) = getList()
	position = [INF for i in range(n)]
	graph = [[] for i in range(n)]
	for i in range(m):
		(a, b, c) = getList()
		graph[a - 1].append((b - 1, c))
		graph[b - 1].append((a - 1, -c))
	visited = [0 for i in range(n)]
	for i in range(n):
		if not visited[i]:
			res = bfs(graph, visited, position, i)
			if res == False:
				print('No')
				return
	print('Yes')
main()


(N, M) = map(int, input().split())
from collections import defaultdict
E = [list() for _ in range(N)]
for _ in range(M):
	(l, r, d) = map(int, input().split())
	E[l - 1].append((r - 1, d))
	E[r - 1].append((l - 1, -d))
locations = [None] * N
for s in range(N):
	if locations[s] is None:
		locations[s] = 0
		stack = [s]
		while stack:
			v = stack.pop()
			p = locations[v]
			for (u, d) in E[v]:
				if locations[u] is None:
					locations[u] = p + d
					stack.append(u)
				elif locations[u] != p + d:
					print('No')
					exit()
print('Yes')


from collections import deque
(N, M) = map(int, input().split())
adjList = [[] for i in range(N)]
for i in range(M):
	(L, R, D) = map(int, input().split())
	adjList[L - 1].append((R - 1, D))
	adjList[R - 1].append((L - 1, -D))

def bfs(vSt):
	xs[vSt] = 0
	Q = deque()
	Q.append(vSt)
	while Q:
		vNow = Q.popleft()
		for (v2, d) in adjList[vNow]:
			x2 = xs[vNow] + d
			if xs[v2] == None:
				xs[v2] = x2
				Q.append(v2)
			elif xs[v2] != x2:
				return False
	return True
xs = [None] * N
for vSt in range(N):
	if xs[vSt] == None:
		if not bfs(vSt):
			print('No')
			exit()
print('Yes')


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

def bfs(graph, start):
	while graph != {}:
		start = min(graph.keys())
		queue = deque([])
		queue.append(start)
		pos = {}
		pos[start] = 0
		while queue:
			u = queue.popleft()
			for (v, d) in graph[u].items():
				if v not in pos:
					pos[v] = pos[u] + d
					if v in graph:
						queue.append(v)
				elif pos[v] != pos[u] + d:
					return False
			del graph[u]
	return True
(n, m) = map(int, input().split())
graph = {}
for i in range(m):
	(l, r, d) = map(int, input().split())
	if l not in graph:
		graph[l] = {}
	graph[l][r] = d
	if r not in graph:
		graph[r] = {}
	graph[r][l] = -d
if m == 0 or bfs(graph, min(graph.keys())):
	print('Yes')
else:
	print('No')


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

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

def union(x, y, w):
	w += weight(x) - weight(y)
	x = find(x)
	y = find(y)
	if x == y:
		return False
	if par[x] > par[y]:
		(x, y) = (y, x)
		w = -w
	par[x] += par[y]
	par[y] = x
	diff_w[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)
(n, m) = map(int, input().split())
par = [-1] * n
diff_w = [0] * n
for _ in range(m):
	(l, r, d) = map(int, input().split())
	if same(l - 1, r - 1):
		if diff(l - 1, r - 1) != d:
			print('No')
			exit()
	else:
		union(l - 1, r - 1, d)
print('Yes')


import sys
sys.setrecursionlimit(10 ** 5)
(N, M) = map(int, input().split())
input = sys.stdin.readline
LRD = [[int(j) for j in input().split()] for _ in range(M)]
data = [x for x in range(N + 1)]
rank = [0] * (N + 1)
diff_weight = [0] * (N + 1)

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

def weight(x):
	return diff_weight[x]

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

def merge(x, y, w):
	w += weight(x)
	w -= weight(y)
	x = root(x)
	y = root(y)
	if x == y:
		return False
	if rank[x] < rank[y]:
		(x, y) = (y, x)
		w = -w
	if rank[x] == rank[y]:
		rank[x] += 1
	data[y] = x
	diff_weight[y] = w
	return True

def issame(x, y):
	return root(x) == root(y)
for i in range(M):
	(L, R, D) = LRD[i]
	if not issame(L, R):
		_ = merge(L, R, D)
	elif diff(L, R) != D:
		print('No')
		exit(0)
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)
for i in range(m):
	(a, b, c) = map(int, input().split())
	if not uf.same(a, b):
		uf.union(a, b, c)
	elif uf.diff(a, b) != c:
		print('No')
		exit()
print('Yes')


import sys
from collections import deque
(n, m) = map(int, input().split())
adj_list = [[] for i in range(n)]
for i in range(m):
	(l, r, d) = map(int, input().split())
	adj_list[l - 1].append((r - 1, d))
	adj_list[r - 1].append((l - 1, -d))

def search(start, dist_all):
	q = deque([start])
	dist_all[i] = 0
	while len(q) > 0:
		w = q.popleft()
		for x in adj_list[w]:
			if dist_all[x[0]] is None:
				dist_all[x[0]] = dist_all[w] + x[1]
				q.append(x[0])
			elif dist_all[x[0]] != dist_all[w] + x[1]:
				return False
	return True
dist_all = [None for i in range(n)]
for i in range(n):
	if dist_all[i] is None:
		if not search(i, dist_all):
			print('No')
			exit(0)
print('Yes')


import sys
sys.setrecursionlimit(2000000)
input = sys.stdin.readline

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [i for i in range(n + 1)]
		self.dist = [0] * (n + 1)

	def find(self, x):
		if self.parents[x] == x:
			return x
		else:
			a = self.parents[x]
			self.parents[x] = self.find(self.parents[x])
			self.dist[x] += self.dist[a]
			return self.parents[x]

	def unite(self, l, r, d):
		rRoot = self.find(r)
		lRoot = self.find(l)
		if rRoot == lRoot:
			if self.dist[l] - self.dist[r] != d:
				print('No')
				exit()
		else:
			newLDist = d + self.dist[r]
			if newLDist >= self.dist[l]:
				self.parents[lRoot] = rRoot
				self.dist[lRoot] = newLDist - self.dist[l]
			else:
				self.parents[rRoot] = lRoot
				self.dist[rRoot] = self.dist[l] - newLDist
(N, M) = map(int, input().split())
tree = UnionFind(N)
for _ in range(M):
	(l, r, d) = map(int, input().split())
	tree.unite(l, r, d)
print('Yes')


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

class Graph:

	class Edge:

		def __init__(self, to, cost):
			(self.to, self.cost) = (to, cost)

	def __init__(self, n, directed=False, decrement=True, destroy=False, edges=[]):
		self.n = n
		self.directed = directed
		self.decrement = decrement
		self.destroy = destroy
		self.edges = [[] for _ in range(self.n)]
		self.dist = [None] * self.n
		self.info = [-1] * self.n
		for (x, y, cost) in edges:
			self.add_edge(x, y, cost)

	def add_edge(self, x, y, cost):
		if self.decrement:
			x -= 1
			y -= 1
		self.edges[x].append(self.Edge(y, cost))
		if self.directed == False:
			self.edges[y].append(self.Edge(x, cost))

	def bfs(self, start, goal=-1, time=0, save=False):
		if self.decrement:
			start -= 1
			goal -= 1
		if not save:
			self.dist = [None] * self.n
		(p, t, dist) = (start, time, 0)
		self.dist[p] = 0
		next_set = deque([(p, t, dist)])
		while next_set:
			(p, t, dist) = next_set.popleft()
			for edge in self.edges[p]:
				(q, cost) = (edge.to, edge.cost)
				if self.dist[q] is not None:
					if self.dist[q] != dist + cost:
						print('No')
						exit()
					continue
				self.dist[q] = dist + cost
				next_set.append((q, t + 1, dist + cost))
		return True
(N, M) = map(int, input().split())
graph = Graph(N, directed=True, decrement=True, destroy=False)
for _ in range(M):
	(x, y, cost) = map(int, input().split())
	graph.add_edge(x, y, cost)
	graph.add_edge(y, x, -cost)
for i in range(1, N + 1):
	if graph.dist[i - 1] is None:
		graph.bfs(i, goal=-1, time=0, save=True)
print('Yes')


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

class WeightedUnionFind:

	def __init__(self, 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):
		px = self.find(x)
		py = self.find(y)
		if px == py:
			return True
		if self.rank[px] == self.rank[py]:
			self.rank[px] += 1
		elif self.rank[px] < self.rank[py]:
			(px, py) = (py, px)
			(x, y) = (y, x)
			w *= -1
		self.par[py] = px
		self.weight[py] = 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]
t = WeightedUnionFind(N + 1)
for (l, r, d) in X:
	if t.same(l, r):
		if t.diff(l, r) != d:
			print('No')
			break
	else:
		t.unite(l, r, d)
else:
	print('Yes')


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline

class WeightedUnionFind:

	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:
			r = self.find(self.par[x])
			self.weight[x] += self.weight[self.par[x]]
			self.par[x] = r
			return r

	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 diff_w(self, x, y):
		return self.weight[x] - self.weight[y]

def main():
	(N, M) = map(int, readline().split())
	m = map(int, read().split())
	LRD = list(zip(m, m, m))
	D = WeightedUnionFind(N)
	for (l, r, d) in LRD:
		l -= 1
		r -= 1
		D.union(l, r, d)
	for (l, r, d) in LRD:
		l -= 1
		r -= 1
		D.find(l)
		D.find(r)
		if d != D.diff_w(l, r):
			print('No')
			sys.exit()
	print('Yes')
main()


from collections import deque

def dfs(s, al, nw, used):
	nw[s] = 0
	q = deque([s])
	used.add(s)
	while q:
		h = q.popleft()
		for (to, ew) in al[h]:
			if to in used:
				if nw[h] + ew != nw[to]:
					return False
				continue
			used.add(to)
			nw[to] = nw[h] + ew
			q.appendleft(to)
	return True

def main():
	(N, M) = map(int, input().split())
	nw = [-1] * N
	al = [[] for i in range(N)]
	for i in range(M):
		(l, r, d) = map(int, input().split())
		al[l - 1].append((r - 1, d))
		al[r - 1].append((l - 1, -d))
	used = set()
	for i in range(N):
		if i in used or dfs(i, al, nw, used):
			continue
		print('No')
		break
	else:
		print('Yes')
main()


import sys
sys.setrecursionlimit(10 ** 5)

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)
		self.rnk = [0] * (n + 1)
		self.weight = [0] * (n + 1)

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

	def GetWeight(self, x):
		self.Find_Root(x)
		return self.weight[x]

	def Unite(self, x, y, w):
		w += self.GetWeight(x)
		w -= self.GetWeight(y)
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return False
		if self.rnk[x] < self.rnk[y]:
			(x, y) = (y, x)
			w = -w
		if self.rnk[x] == self.rnk[y]:
			self.rnk[x] += 1
		self.root[y] = x
		self.weight[y] = w
		return True

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return -self.root[self.Find_Root(x)]

	def Diff(self, x, y):
		return self.GetWeight(y) - self.GetWeight(x)

def main():
	(N, M) = map(int, input().split())
	lrd = [list(map(int, input().split())) for _ in range(M)]
	U = UnionFind(N)
	for i in range(M):
		(l, r, d) = lrd[i]
		if not U.isSameGroup(l, r):
			U.Unite(l, r, d)
		elif U.Diff(l, r) != d:
			print('No')
			exit()
	print('Yes')
main()


import sys
sys.setrecursionlimit(10 ** 6)

def dfs(p):
	for edge in G[p]:
		if X[edge[0]] is not None:
			if X[edge[0]] - X[p] != edge[1]:
				print('No')
				exit()
		else:
			X[edge[0]] = X[p] + edge[1]
			dfs(edge[0])
(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))
X = [None] * N
for i in range(N):
	if X[i] is None:
		X[i] = 0
		dfs(i)
print('Yes')


from collections import deque
import sys
sys.setrecursionlimit(10 ** 7)
(N, M) = map(int, input().split())
Graph = [[] for i in range(N)]
for i in range(M):
	(L, R, D) = map(int, input().split())
	Graph[L - 1].append((R - 1, D))
	Graph[R - 1].append((L - 1, -D))
visit = [False] * N
dist = [0] * N
for i in range(N):
	if visit[i] == False:
		visit[i] = True
		A = deque()
		A.append(i)
		while A:
			x = A.pop()
			for (y, d) in Graph[x]:
				if visit[y] == True and dist[y] != d + dist[x]:
					print('No')
					sys.exit()
				elif visit[y] == False:
					visit[y] = True
					A.append(y)
					dist[y] = d + dist[x]
print('Yes')


(N, M) = map(int, input().split())
parent = list(range(N + 1))
rank = [0] * (N + 1)
pardist = [0] * (N + 1)

def getRoot(x):
	if parent[x] == x:
		return (x, 0)
	else:
		(parent[x], dist) = getRoot(parent[x])
		pardist[x] += dist
		return (parent[x], pardist[x])

def unite(left, right, dist):
	(lRoot, lPardist) = getRoot(left)
	(rRoot, rPardist) = getRoot(right)
	if lRoot == rRoot:
		if -(rPardist - lPardist) != dist:
			print('No')
			exit()
	elif rank[lRoot] < rank[rRoot]:
		parent[lRoot] = rRoot
		pardist[lRoot] = dist + rPardist - lPardist
	else:
		parent[rRoot] = lRoot
		pardist[rRoot] = -(dist + rPardist - lPardist)
		if rank[lRoot] == rank[rRoot]:
			rank[lRoot] += 1
for i in range(M):
	(l, r, d) = map(int, input().split())
	unite(l, r, d)
print('Yes')


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)
		self.rnk = [0] * (n + 1)

	def Find_Root(self, x):
		if self.root[x] < 0:
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return -self.root[self.Find_Root(x)]
import sys
input = sys.stdin.readline
(N, M) = map(int, input().split())
graph = [[] for _ in range(N)]
uni = UnionFind(N)
for _ in range(M):
	(a, b, d) = map(int, input().split())
	uni.Unite(a - 1, b - 1)
	graph[a - 1].append((d, b - 1))
	graph[b - 1].append((-d, a - 1))
INF = 10 ** 14
A = [INF] * N

def bfs(start):
	q = [start]
	A[start] = 0
	while q:
		qq = []
		for p in q:
			for (d, np) in graph[p]:
				if A[np] == INF:
					A[np] = A[p] + d
					qq.append(np)
				elif A[np] != A[p] + d:
					return False
		q = qq
	return True
root = set()
for i in range(N):
	root.add(uni.Find_Root(i))
ok = True
for r in root:
	ok = ok and bfs(r)
print('Yes' if ok else '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 unite(self, x, y, w):
		px = self.find(x)
		py = self.find(y)
		if px != py:
			if self.rank[px] < self.rank[py]:
				self.par[px] = py
				self.weight[px] = w - self.weight[x] + self.weight[y]
			else:
				self.par[py] = px
				self.weight[py] = -w - self.weight[y] + self.weight[x]
				if self.rank[px] == self.rank[py]:
					self.rank[px] += 1

	def are_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 = [list(map(int, input().split())) for i in range(M)]
graph = WeightedUnionFind(N)
for (l, r, d) in LRD:
	l -= 1
	r -= 1
	if graph.are_same(l, r):
		if graph.diff(l, r) != d:
			print('No')
			break
	else:
		graph.unite(l, r, d)
else:
	print('Yes')


ai = lambda : list(map(int, input().split()))
(n, m) = ai()
from collections import defaultdict
dd = defaultdict(list)
for _ in range(m):
	(l, r, d) = ai()
	dd[l].append((r, d))
	dd[r].append((l, -d))
pos = [None] * (n + 1)
for i in range(1, n + 1):
	if pos[i] is not None:
		continue
	pos[i] = 0
	stack = [i]
	while stack:
		s = stack.pop()
		for (p, d) in dd[s]:
			if pos[p] is None:
				pos[p] = pos[s] + d
				stack.append(p)
			elif pos[p] != pos[s] + d:
				print('No')
				exit()
print('Yes')


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

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())
Un = WeightedUnionFind(N + 1)
ans = 'Yes'
for _ in range(M):
	(l, r, w) = map(int, input().split())
	if Un.same(l, r):
		if Un.diff(l, r) != w:
			ans = 'No'
			break
	else:
		Un.union(l, r, w)
print(ans)


class WeightedUnionFind:

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

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

	def union(self, x, y, w):
		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]:
			self.parents[y] += self.parents[x]
			self.parents[x] = y
			self.par_weight[x] = -w
		else:
			self.parents[x] += self.parents[y]
			self.parents[y] = x
			self.par_weight[y] = w

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

	def diff(self, x, y):
		if self.find(x) != self.find(y):
			raise Exception('"{}" belongs to a different tree from "{}"'.format(x, y))
		return self.weight(y) - self.weight(x)
(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.find(L) == uf.find(R):
		if uf.diff(L, R) != D:
			res = 'No'
			break
	else:
		uf.union(L, R, D)
else:
	res = 'Yes'
print(res)


from collections import deque
(N, M) = map(int, input().split())
value_list = [0] * N
done_list = [-1] * N
res = 'Yes'
G = dict()
for i in range(N):
	G[i] = dict()
for _ in range(M):
	(L, R, D) = map(int, input().split())
	G[L - 1][R - 1] = D
	G[R - 1][L - 1] = -D
	done_list[L - 1] = 0
	done_list[R - 1] = 0
pick = 0
while pick < N and res == 'Yes':
	queue = deque([pick])
	done_list[pick] = 1
	value_list[pick] = 0
	while len(queue) > 0:
		L = queue.popleft()
		for R in G[L].keys():
			if done_list[R] == 0:
				done_list[R] = 1
				value_list[R] = value_list[L] + G[L][R]
				queue.append(R)
			elif value_list[R] != value_list[L] + G[L][R]:
				res = 'No'
	while pick < N:
		if done_list[pick] == 0:
			break
		pick += 1
print(res)


def solve(N, M, lrd):
	edges = {}
	nodes = {}
	for (l, r, d) in lrd:
		if not l in edges:
			edges[l] = {}
		if not r in edges:
			edges[r] = {}
		edges[l][r] = d
		edges[r][l] = -d
		nodes[l] = None
		nodes[r] = None
	for node in nodes:
		if nodes[node] is not None:
			continue
		nodes[node] = 0
		stack = []
		stack.append(node)
		while stack:
			node = stack.pop()
			for (n, d) in edges[node].items():
				if nodes[n] is None:
					stack.append(n)
					nodes[n] = nodes[node] + edges[node][n]
				elif nodes[n] != nodes[node] + edges[node][n]:
					return False
	return True
(N, M) = [int(x) for x in input().split()]
lrd = []
for i in range(M):
	lrd.append([int(x) for x in input().split()])
if solve(N, M, lrd):
	print('Yes')
else:
	print('No')


from collections import deque

def inpl():
	return tuple(map(int, input().split()))
(N, M) = inpl()
adj = [[] for _ in range(N + 1)]
for _ in range(M):
	(l, r, d) = inpl()
	adj[l].append([r, d])
	adj[r].append([l, -d])
X = [-1 for _ in range(N + 1)]
searched = [False for _ in range(N + 1)]
S = 0
res = True
g = 1
Q = deque([])
for g in range(1, N + 1):
	if searched[g]:
		continue
	X[g] = 0
	Q.append(g)
	searched[g] = True
	while Q:
		p = Q.popleft()
		for (np, d) in adj[p]:
			if searched[np]:
				if X[np] != X[p] + d:
					Q = []
					res = False
					break
			else:
				X[np] = X[p] + d
				Q.append(np)
				searched[np] = True
	if not res:
		break
if res:
	print('Yes')
else:
	print('No')


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [i for i in range(n + 1)]
		self.dict = [0] * (N + 1)

	def find(self, x):
		if self.parents[x] == x:
			return x
		else:
			self.find(self.parents[x])
			u = self.dict[self.parents[x]]
			self.parents[x] = self.find(self.parents[x])
			self.dict[x] += u
			return self.parents[x]

	def unite(self, x, y, d):
		xRoot = self.find(x)
		yRoot = self.find(y)
		if xRoot == yRoot:
			if self.dict[x] - self.dict[y] != d:
				print('No')
				exit()
		if self.dict[y] + d > self.dict[x]:
			self.parents[xRoot] = yRoot
			self.dict[xRoot] = self.dict[y] + d - self.dict[x]
		else:
			self.parents[yRoot] = xRoot
			self.dict[yRoot] = self.dict[x] - (self.dict[y] + d)
(N, M) = map(int, input().split())
tree = UnionFind(N)
for _ in range(M):
	(l, r, d) = map(int, input().split())
	tree.unite(l, r, d)
print('Yes')


(n, m) = map(int, input().split())
p = list(range(n + 1))
x = [0] * (n + 1)

def find(i):
	if p[i] == i:
		return i
	(p[i], x[i]) = (find(p[i]), x[i] + x[p[i]])
	return p[i]
for _ in range(m):
	(l, r, d) = map(int, input().split())
	pl = find(l)
	pr = find(r)
	if pl == pr and x[r] - x[l] != d:
		print('No')
		break
	else:
		p[pr] = pl
		x[pr] = x[l] + d - x[r]
else:
	print('Yes')


class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [i for i in range(n + 1)]
		self.dist = [0] * (n + 1)

	def find(self, x):
		if self.parents[x] == x:
			return x
		else:
			p = self.parents[x]
			self.parents[x] = self.find(self.parents[x])
			self.dist[x] += self.dist[p]
			return self.parents[x]

	def unite(self, x, y, d):
		xRoot = self.find(x)
		yRoot = self.find(y)
		if xRoot == yRoot:
			if self.dist[x] - self.dist[y] != d:
				print('No')
				exit()
		else:
			diff = self.dist[y] + d - self.dist[x]
			if diff >= 0:
				self.parents[xRoot] = yRoot
				self.dist[xRoot] += diff
				self.find(x)
			else:
				self.parents[yRoot] = xRoot
				self.dist[yRoot] += abs(diff)
				self.find(y)
(N, M) = map(int, input().split())
tree = UnionFind(N)
for _ in range(M):
	(L, R, D) = map(int, input().split())
	tree.unite(L, R, D)
print('Yes')


import sys
sys.setrecursionlimit(10 ** 8)

def find(x):
	global table
	global diff_weight
	if table[x] == x:
		return x
	else:
		root = find(table[x])
		diff_weight[x] += diff_weight[table[x]]
		table[x] = root
		return table[x]

def union(x, y, w):
	w = w - weight(y) + weight(x)
	x = find(x)
	y = find(y)
	if x == y:
		return
	if rank[x] < rank[y]:
		(x, y) = (y, x)
		w = -w
	table[y] = x
	diff_weight[y] = w
	if rank[x] == rank[y]:
		rank[y] += 1

def check(x, y):
	if find(x) == find(y):
		return True
	else:
		return False

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

def diff(x, y):
	return weight(y) - weight(x)
(N, M) = map(int, input().split())
table = [i for i in range(N)]
rank = [1 for i in range(N)]
diff_weight = [0 for i in range(N)]
for i in range(M):
	(a, b, D) = map(int, input().split())
	a -= 1
	b -= 1
	if check(a, b):
		if diff(a, b) != D:
			print('No')
			sys.exit()
	else:
		union(a, b, D)
print('Yes')


def ascend(anc, union, dist, rec):
	count = 0
	while anc != union[anc]:
		rec[count] = anc
		anc = union[anc]
		count += 1
	rec[count] = anc
	for i in range(count - 1, -1, -1):
		dist[rec[i]] += dist[rec[i + 1]]
		union[rec[i]] = anc
	return anc

def connect(l, r, d, union, dist, rec):
	l_anc = ascend(l, union, dist, rec)
	r_anc = ascend(r, union, dist, rec)
	if l_anc != r_anc:
		union[l_anc] = r_anc
		dist[l_anc] = dist[r] + d - dist[l]

def is_union(l, r, union, dist, rec):
	return ascend(l, union, dist, rec) == ascend(r, union, dist, rec)

def main():
	(N, M) = map(int, input().split())
	union = list(range(N + 1))
	dist = [0] * (N + 1)
	rec = [0] * (N + 1)
	for i in range(M):
		(l, r, d) = map(int, input().split())
		if is_union(l, r, union, dist, rec):
			if dist[r] + d != dist[l]:
				print('No')
				break
		else:
			connect(l, r, d, union, dist, rec)
	else:
		print('Yes')
main()


class WeightedUnionFind(object):

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

	def root(self, x):
		if self.par[x] == x:
			return x
		else:
			y = self.root(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.root(x)
		ry = self.root(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.root(x) == self.root(y)

	def diff(self, x, y):
		return self.weight[x] - self.weight[y]
(n, m) = map(int, input().split())
wuf = WeightedUnionFind(n)
for _ in range(m):
	(l, r, d) = map(int, input().split())
	(l, r) = (l - 1, r - 1)
	if wuf.same(l, r) and wuf.diff(l, r) != d:
		print('No')
		exit()
	wuf.unite(l, r, d)
print('Yes')


from collections import *

class UnionFind:

	def __init__(self, size):
		self.table = [-1] * size

	def root(self, x):
		while self.table[x] >= 0:
			x = self.table[x]
		return x

	def unite(self, x, y):
		s1 = self.root(x)
		s2 = self.root(y)
		if s1 != s2:
			if self.table[s1] > self.table[s2]:
				(s1, s2) = (s2, s1)
			self.table[s1] += self.table[s2]
			self.table[s2] = s1
		return

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

	def size(self, x):
		return -self.table[self.root(x)]
(n, m, *t) = map(int, open(0).read().split())
u = UnionFind(n + 1)
f = defaultdict(list)
e = defaultdict(list)
for (l, r, d) in zip(t[::3], t[1::3], t[2::3]):
	u.unite(l, r)
	e[l].append((r, d))
for i in range(n + 1):
	f[u.root(i)].append(i)
for t in f.values():
	if len(t) < 3:
		continue
	outs = defaultdict(list)
	ins = defaultdict(int)
	for i in t:
		outs[i] = [j for (j, v) in e[i]]
		for j in outs[i]:
			ins[j] += 1
	q = deque((v1 for v1 in t if ins[v1] == 0))
	res = []
	while q:
		v1 = q.popleft()
		res.append(v1)
		for v2 in outs[v1]:
			ins[v2] -= 1
			if ins[v2] == 0:
				q.append(v2)
	if not res:
		print('No')
		exit()
	c = defaultdict(int)
	for i in res:
		for (j, v) in e[i]:
			if c[j] and c[j] != c[i] + v:
				print('No')
				exit()
			c[j] = c[i] + v
print('Yes')


from collections import defaultdict

class XUnionFind(object):

	def __init__(self):
		self.table = defaultdict(lambda : -1)
		self.dtable = defaultdict(lambda : 0)

	def find(self, x):
		parent = self.table[x]
		if parent < 0:
			return (x, 0)
		else:
			(root, distance) = self.find(parent)
			new_distance = distance + self.dtable[x]
			self.table[x] = root
			self.dtable[x] = new_distance
			return (root, new_distance)

	def union(self, x1, x2, d=0):
		(root1, distance1) = self.find(x1)
		(root2, distance2) = self.find(x2)
		if root1 == root2:
			if distance2 - distance1 != d:
				return False
			return True
		if root1 < root2:
			self.table[root1] += self.table[root2]
			self.table[root2] = root1
			self.dtable[root2] = distance1 + d - distance2
		else:
			self.table[root2] += self.table[root1]
			self.table[root1] = root2
			self.dtable[root1] = distance2 - d - distance1
		return True

def solve(N, M, lrd):
	uf = XUnionFind()
	for (l, r, d) in lrd:
		rc = uf.union(l, r, d)
		if rc == False:
			return False
	return True
(N, M) = [int(x) for x in input().split()]
lrd = []
for i in range(M):
	lrd.append([int(x) for x in input().split()])
if solve(N, M, lrd):
	print('Yes')
else:
	print('No')


(N, M) = map(int, input().split())
lines = [None] * N
stack = [0]
edges = [[] for _ in range(N)]
for _ in range(M):
	(l, r, d) = map(int, input().split())
	edges[l - 1].append((r - 1, d))
	edges[r - 1].append((l - 1, -d))
for i in range(N):
	if lines[i] is not None:
		continue
	lines[i] = 0
	stack = [i]
	while stack:
		v = stack.pop()
		for (u, d) in edges[v]:
			if lines[u] is None:
				lines[u] = lines[v] + d
				stack.append(u)
			elif lines[v] + d != lines[u]:
				print('No')
				quit()
print('Yes')


import sys
from collections import defaultdict, deque
YES = 'Yes'
NO = 'No'

def solve(N: int, M: int, adj):
	visited = [False] * N
	pos = [None] * N
	for (i, vis) in enumerate(visited):
		if vis:
			continue
		pos[i] = 0
		visited[i] = True
		Q = deque([i], M)
		while len(Q) > 0:
			u = Q.popleft()
			for (v, d) in adj[u]:
				if pos[v] is None:
					pos[v] = pos[u] + d
				elif pos[v] != pos[u] + d:
					print(NO)
					return
				if visited[v]:
					continue
				Q.append(v)
				visited[v] = True
	print(YES)
	return

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))
	adj = [set() for _ in range(N)]
	for i in range(M):
		l = int(next(tokens)) - 1
		r = int(next(tokens)) - 1
		d = int(next(tokens))
		adj[l].add((r, d))
		adj[r].add((l, -d))
	solve(N, M, adj)
main()


(n, m) = map(int, input().split())
lef = list(range(n + 1))
ran = [0] * (n + 1)

def f(x):
	if lef[x] == x:
		return x
	(lef[x], ran[x]) = (f(lef[x]), ran[x] + ran[lef[x]])
	return lef[x]
for i in range(m):
	(l, r, d) = map(int, input().split())
	a = f(l)
	b = f(r)
	if a == b and ran[r] - ran[l] != d:
		print('No')
		exit()
	else:
		lef[b] = a
		ran[b] = ran[l] + d - ran[r]
print('Yes')


import sys
sys.setrecursionlimit(2000000)
input = sys.stdin.readline

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.parents = [i for i in range(n + 1)]
		self.distance = [0] * (n + 1)

	def find(self, x):
		if self.parents[x] == x:
			return (x, 0)
		else:
			(self.parents[x], dist2) = self.find(self.parents[x])
			self.distance[x] += dist2
			return (self.parents[x], self.distance[x])

	def union(self, l, r, dist):
		(lRoot, lDist) = self.find(l)
		(rRoot, rDist) = self.find(r)
		if lRoot == rRoot and lDist - rDist != dist:
			print('No')
			exit()
		if lDist < dist + rDist:
			self.parents[lRoot] = rRoot
			self.distance[lRoot] = dist + rDist - lDist
		else:
			self.parents[rRoot] = lRoot
			self.distance[rRoot] = lDist - (dist + rDist)
(N, M) = map(int, input().split())
tree = UnionFind(N)
for i in range(M):
	(L, R, D) = map(int, input().split())
	tree.union(L, R, D)
print('Yes')


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

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

def diff(u, v):
	return weight(v) - weight(u)

def unite(u, v, w):
	w += diff(v, u)
	u = root(u)
	v = root(v)
	if u == v:
		return
	if rank[u] < rank[v]:
		(u, v) = (v, u)
		w = -w
	par[v] = u
	diff_weight[v] = w
	if rank[u] == rank[v]:
		rank[u] += 1

def same(u, v):
	return root(u) == root(v)
(N, M) = map(int, input().split())
par = list(range(N))
rank = [0] * N
diff_weight = [0] * N
for _ in range(M):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	if same(l, r):
		dist = diff(l, r)
		if dist != d:
			print('No')
			exit()
	else:
		unite(l, r, d)
print('Yes')


(N, M) = map(int, input().split())
xval = [float('INF')] * (N + 1)
road = {}
for i in range(1, N + 1):
	road[i] = {}
for i in range(M):
	(r, l, d) = map(int, input().split())
	road[r][l] = d
	road[l][r] = -d
checked = set()
i = 1
while len(checked) < N:
	for j in range(i, N + 1):
		if j in checked:
			continue
		else:
			i = j
			checked.add(i)
			break
	xval[i] = 0
	check = set([i])
	while len(check) > 0:
		nextcheck = set()
		for x in check:
			for y in road[x].keys():
				if xval[y] == float('INF'):
					xval[y] = xval[x] + road[x][y]
					checked.add(y)
					nextcheck.add(y)
				elif xval[y] != xval[x] + road[x][y]:
					print('No')
					exit()
				else:
					continue
		check = nextcheck
print('Yes')


from collections import deque

class Edge:

	def __init__(self, t, w):
		self.to = t
		self.ew = w

class Graph:

	def __init__(self, N):
		self.nw = [-1] * N
		self.al = [[] for i in range(N)]

	def add_edge(self, fr, to, weight):
		self.al[fr].append(Edge(to, weight))
		self.al[to].append(Edge(fr, -weight))

	def dfs(self, s, used):
		self.nw[s] = 0
		q = deque([s])
		used.add(s)
		while q:
			h = q.popleft()
			for e in self.al[h]:
				if e.to in used:
					if self.nw[h] + e.ew != self.nw[e.to]:
						return False
					continue
				used.add(e.to)
				self.nw[e.to] = self.nw[h] + e.ew
				q.appendleft(e.to)
		return True

def main():
	(N, M) = map(int, input().split())
	graph = Graph(N)
	for i in range(M):
		(l, r, d) = map(int, input().split())
		graph.add_edge(l - 1, r - 1, d)
	used = set()
	for i in range(N):
		if i in used or graph.dfs(i, used):
			continue
		print('No')
		break
	else:
		print('Yes')
main()


from collections import deque
(N, M) = map(int, input().split())
graph = [[] for i in range(N)]
for i in range(M):
	(L, R, D) = map(int, input().split())
	graph[L - 1].append([R - 1, D])
	graph[R - 1].append([L - 1, -D])
dist = [int(10000000000.0)] * N

def bfs(id):
	Q = deque()
	Q.append(id)
	dist[id] = 0
	while len(Q) != 0:
		v = Q.popleft()
		for edge in graph[v]:
			(u, d) = (edge[0], edge[1])
			if dist[u] == int(10000000000.0):
				dist[u] = dist[v] + d
				Q.append(u)
			elif dist[u] != dist[v] + d:
				print('No')
				exit()
for i in range(N):
	if dist[i] == int(10000000000.0):
		bfs(i)
print('Yes')


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

class WeightedUnionFind:

	def __init__(self, x):
		self.p = [e for e in range(x)]
		self.rank = [0] * x
		self.weight = [0] * x

	def same(self, u, v):
		return self.find_set(u) == self.find_set(v)

	def find_set(self, u):
		if u != self.p[u]:
			v = self.find_set(self.p[u])
			self.weight[u] += self.weight[self.p[u]]
			self.p[u] = v
		return self.p[u]

	def unite(self, u, v, w):
		w += self.weight[u]
		w -= self.weight[v]
		u = self.find_set(u)
		v = self.find_set(v)
		if self.rank[u] < self.rank[v]:
			(u, v) = (v, u)
			w = -w
		if self.rank[u] == self.rank[v]:
			self.rank[u] += 1
		self.p[v] = u
		self.weight[v] = w

	def get_weight(self, u):
		self.find_set(u)
		return self.weight[u]

	def diff(self, u, v):
		return self.get_weight(v) - self.get_weight(u)
wuf = WeightedUnionFind(n)
for (l, r, d) in lrd:
	l -= 1
	r -= 1
	if wuf.same(l, r):
		if wuf.diff(l, r) != d:
			print('No')
			exit()
	else:
		wuf.unite(l, r, d)
print('Yes')


from collections import deque
(n, m) = map(int, input().split())
graph = {i: {} for i in range(1, n + 1)}
for _ in range(m):
	(a, b, c) = map(int, input().split())
	graph[a][b] = c
	graph[b][a] = -c
distance = ['inf' for i in range(n + 1)]
visited = [False for i in range(n + 1)]
visited[0] = True

def find(x):
	d = deque()
	visited[x] = True
	distance[x] = 0
	d.append(x)
	flag = True
	while d and flag:
		x = d.popleft()
		for node in graph[x]:
			if visited[node] == False:
				visited[node] = True
				d.append(node)
				if distance[node] == 'inf':
					distance[node] = distance[x] + graph[x][node]
				elif distance[node] != distance[x] + graph[x][node]:
					flag = False
					break
			elif visited[node] == True:
				if distance[node] != distance[x] + graph[x][node]:
					flag = False
					break
	if flag:
		return False
	else:
		return True
all_flag = True
not_visited = True
while not_visited and all_flag:
	judge = False
	for i in range(1, n + 1):
		if visited[i] == False:
			judge = True
			if find(i):
				all_flag = False
				break
			else:
				pass
	if not judge:
		not_visited = False
if all_flag:
	print('Yes')
else:
	print('No')


class UnionFind:

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

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

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

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

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

	def unite(self, x, y, w):
		w += self.weight(x)
		w -= self.weight(y)
		x = self.root(x)
		y = self.root(y)
		if self.rank[x] < self.rank[y]:
			(x, y) = (y, x)
			w = -w
		if self.rank[x] == self.rank[y]:
			self.rank[x] += 1
		self.par[y] = x
		self.diff_weight[y] = w
import sys
sys.setrecursionlimit(10 ** 7)

def LI():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def S():
	return sys.stdin.readline().rstrip()
(N, M) = map(int, S().split())
G = UnionFind(N)
for i in range(M):
	(L, R, D) = LI()
	if G.same_check(L, R):
		if G.diff(L, R) != D:
			print('No')
			exit()
	else:
		G.unite(L, R, D)
print('Yes')


class WeightedUnionFind:

	def __init__(self, numV):
		self.pars = list(range(numV))
		self.ranks = [0] * numV
		self.weights = [0] * numV

	def find(self, x):
		if self.pars[x] == x:
			return x
		else:
			parXOld = self.pars[x]
			self.pars[x] = self.find(parXOld)
			self.weights[x] += self.weights[parXOld]
			return self.pars[x]

	def union(self, x, y, wt):
		wtX = self.getWeight(x)
		wtY = self.getWeight(y)
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return wtY == wtX + wt
		wt += wtX - wtY
		if self.ranks[x] < self.ranks[y]:
			self.pars[x] = y
			self.weights[x] = -wt
		else:
			self.pars[y] = x
			self.weights[y] = wt
			if self.ranks[x] == self.ranks[y]:
				self.ranks[x] += 1
		return True

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

	def getWeight(self, x):
		self.find(x)
		return self.weights[x]

	def getDiff(self, x, y):
		if self.find(x) == self.find(y):
			return self.getWeight(y) - self.getWeight(x)
		else:
			return float('inf')
(N, M) = map(int, input().split())
WUF = WeightedUnionFind(N)
ans = 'Yes'
for _ in range(M):
	(L, R, D) = map(int, input().split())
	if not WUF.union(L - 1, R - 1, D):
		ans = 'No'
print(ans)


class WeightedUnionFindTree:

	def __init__(self, n_nodes):
		self.par = [i for i in range(n_nodes)]
		self.rank = [0] * n_nodes
		self.weights = [0] * n_nodes

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

	def unite(self, x, y, weight=0):
		(root_x, root_y) = (self.find(x), self.find(y))
		if root_x == root_y:
			return
		if self.rank[root_x] < self.rank[root_y]:
			self.par[root_x] = root_y
			self.weights[root_x] = weight - self.weights[x] + self.weights[y]
		else:
			self.par[root_y] = root_x
			self.weights[root_y] = -weight - self.weights[y] + self.weights[x]
			if self.rank[root_x] == self.rank[root_y]:
				self.rank[root_x] += 1

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

	def diff(self, x, y):
		return self.weights[x] - self.weights[y]
(N, M) = map(int, input().split())
uft = WeightedUnionFindTree(N)
for _ in range(M):
	(l, r, d) = map(int, input().split())
	(l, r) = (l - 1, r - 1)
	if not uft.is_same(l, r):
		uft.unite(l, r, d)
	elif uft.diff(l, r) != d:
		print('No')
		quit()
else:
	print('Yes')


(N, M) = map(int, input().split())
edge = [set() for _ in range(N + 1)]
for _ in range(M):
	(l, r, d) = map(int, input().split())
	edge[l].add((r, d))
	edge[r].add((l, -d))
loc = {}
for i in range(1, N + 1):
	stack = []
	if i not in loc:
		loc[i] = 0
		stack.append(i)
	while stack:
		s = stack.pop()
		for (t, d) in edge[s]:
			if t not in loc:
				loc[t] = loc[s] + d
				stack.append(t)
			elif loc[t] != loc[s] + d:
				print('No')
				exit()
print('Yes')


import sys
from collections import deque, defaultdict
import copy
import bisect
import math
import heapq
from itertools import combinations, permutations
import sys

def input():
	return sys.stdin.readline().strip()
(N, M) = list(map(int, input().split()))
default = 100000000000000000000000
graph = [[] for _ in range(N)]
dist = [default for _ in range(N)]
for i in range(M):
	(L, R, D) = list(map(int, input().split()))
	L -= 1
	R -= 1
	graph[L].append([R, D])
	graph[R].append([L, -D])
loc = 0
while loc < N:
	if dist[loc] == default:
		dist[loc] = 0
		que = deque([])
		que.append(loc)
		while len(que) > 0:
			node = que.popleft()
			if len(graph[node]) > 0:
				for edge in graph[node]:
					if dist[edge[0]] == default:
						dist[edge[0]] = dist[node] + edge[1]
						que.append(edge[0])
					elif dist[edge[0]] != dist[node] + edge[1]:
						print('No')
						exit()
	loc += 1
print('Yes')


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 15
mod = 10 ** 9 + 7

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

def main():
	(n, m) = LI()
	e = [[] for _ in range(n)]
	if m > 0:
		for _ in range(m):
			(l, r, d) = LI()
			e[l - 1].append((r - 1, d))
			e[r - 1].append((l - 1, -d))
	b = [None] * n
	for i in range(n):
		if not b[i] is None:
			continue
		b[i] = 0
		q = [i]
		qi = 0
		nq = []
		while True:
			if len(q) == qi:
				if not nq:
					break
				q = nq
				qi = 0
				nq = []
			j = q[qi]
			qi += 1
			c = b[j]
			for (r, d) in e[j]:
				if b[r] is None:
					b[r] = c + d
					nq.append(r)
				elif b[r] != c + d:
					return 'No'
	return 'Yes'
print(main())


import sys
sys.setrecursionlimit(10 ** 6)
INF = 10 ** 9
(N, M) = map(int, input().split())

def dfs(u, d1):
	pos_list[u] = d1
	for (v, d2) in graph[u]:
		if pos_list[v] == -INF:
			dfs(v, d1 + d2)
		elif pos_list[v] != d1 + d2:
			print('No')
			sys.exit(0)
	return
graph = []
for i in range(N + 1):
	graph.append([])
for i in range(M):
	(L, R, D) = map(int, input().split())
	graph[L].append((R, D))
	graph[R].append((L, -D))
pos_list = [-INF] * (N + 1)
for i in range(1, N + 1):
	if pos_list[i] != -INF:
		continue
	dfs(i, 0)
print('Yes')


import sys
readline = sys.stdin.readline

class UFP:

	def __init__(self, num):
		self.par = [-1] * num
		self.dist = [0] * num

	def find(self, x):
		if self.par[x] < 0:
			return x
		else:
			res = 0
			xo = x
			while self.par[x] >= 0:
				res += self.dist[x]
				x = self.par[x]
			self.dist[xo] = res
			self.par[xo] = x
			return x

	def union(self, x, y, d):
		rx = self.find(x)
		ry = self.find(y)
		if rx != ry:
			if self.par[rx] > self.par[ry]:
				(rx, ry) = (ry, rx)
				(x, y) = (y, x)
				d = -d
			self.par[rx] += self.par[ry]
			self.par[ry] = rx
			self.dist[ry] = d + self.dist[x] - self.dist[y]
			return True
		else:
			if d + self.dist[x] - self.dist[y]:
				return False
			return True
(N, M) = map(int, readline().split())
T = UFP(N)
ans = 'No'
for _ in range(M):
	(l, r, d) = map(int, readline().split())
	l -= 1
	r -= 1
	if not T.union(l, r, d):
		break
else:
	ans = 'Yes'
print(ans)


vs = set()
from collections import defaultdict

def dfs_w(d, stack):
	depthh = defaultdict(int)
	path = [0]
	pvs = set()
	if stack[0] in vs:
		return True
	while stack:
		(v, dpd) = stack.pop()
		if v > 0:
			parent = path[-1]
			path.append(v)
			vs.add(v)
			pvs.add(v)
			depthh[v] = depthh[parent] + dpd
			for (u, dpd) in d[v]:
				if u in pvs:
					if depthh[u] != depthh[v] + dpd:
						return False
				if u in vs:
					continue
				stack += [(-v, dpd), (u, dpd)]
		else:
			path.pop()
	return True
(N, M) = map(int, input().split())
G = [set() for _ in range(N + 1)]
for _ in range(M):
	(a, b, c) = map(int, input().split())
	G[a].add((b, c))
	G[b].add((a, -c))
for i in range(N):
	if i in vs:
		continue
	stack = [(i + 1, 0)]
	r = dfs_w(G, stack)
	if not r:
		break
if r:
	print('Yes')
else:
	print('No')


import sys
stdin = sys.stdin
sys.setrecursionlimit(10 ** 7)

def li():
	return map(int, stdin.readline().split())

def li_():
	return map(lambda x: int(x) - 1, stdin.readline().split())

def lf():
	return map(float, stdin.readline().split())

def ls():
	return stdin.readline().split()

def ns():
	return stdin.readline().rstrip()

def lc():
	return list(ns())

def ni():
	return int(stdin.readline())

def nf():
	return float(stdin.readline())

class WeightedUnionFind:

	def __init__(self, node: int) -> None:
		self.n = node
		self.par = [i for i in range(self.n)]
		self.rank = [0 for i in range(self.n)]
		self.diff_weight = [0 for i in range(self.n)]

	def find(self, x: int) -> int:
		if x == self.par[x]:
			return x
		else:
			r = self.find(self.par[x])
			self.diff_weight[x] += self.diff_weight[self.par[x]]
			self.par[x] = r
			return self.par[x]

	def weight(self, x: int) -> int:
		self.find(x)
		return self.diff_weight[x]

	def unite(self, x: int, y: int, w: int) -> bool:
		if self.isSame(x, y):
			return False
		w += self.weight(x)
		w -= self.weight(y)
		rx = self.find(x)
		ry = self.find(y)
		if self.rank[rx] < self.rank[ry]:
			(rx, ry) = (ry, rx)
			w = -w
		self.par[ry] = self.par[rx]
		self.diff_weight[ry] = w
		if self.rank[rx] == self.rank[ry]:
			self.rank[rx] += 1
		return True

	def isSame(self, x: int, y: int) -> bool:
		return self.find(x) == self.find(y)

	def diff(self, x: int, y: int) -> int:
		if self.isSame(x, y):
			return self.weight(y) - self.weight(x)
		else:
			raise ValueError('xとyは同じ木に属していません')

def judge(wuf, state):
	for (l, r, d) in state:
		if wuf.diff(l, r) != d:
			return False
	return True
(n, m) = li()
wuf = WeightedUnionFind(n)
lrd = []
for _ in range(m):
	(l, r, d) = li()
	l -= 1
	r -= 1
	lrd.append((l, r, d))
	wuf.unite(l, r, d)
print('Yes' if judge(wuf, lrd) else 'No')


from collections import deque
(N, M) = map(int, input().split())
Inf = 10000000000
Edge = [[] for i in range(N)]
for i in range(M):
	(l, r, d) = map(int, input().split())
	Edge[l - 1].append((r - 1, d))
	Edge[r - 1].append((l - 1, -d))
Node = [Inf for i in range(N)]
Possible = True
for i in range(N):
	if not Possible:
		break
	elif Node[i] == Inf:
		Node[i] = 0
		Q = deque([i])
		while Q:
			now = Q.popleft()
			for e in Edge[now]:
				if Node[e[0]] == Inf:
					Node[e[0]] = Node[now] + e[1]
					Q.append(e[0])
				elif Node[now] + e[1] != Node[e[0]]:
					Possible = False
					break
print('Yes' if Possible else 'No')


from collections import deque
(n, m) = map(int, input().split())
edge = {}
for _ in range(m):
	(l, r, d) = map(int, input().split())
	if l not in edge:
		edge[l] = []
	edge[l].append([r, d])
	if r not in edge:
		edge[r] = []
	edge[r].append([l, -1 * d])
x = [None for _ in range(n + 1)]
for i in range(1, n + 1):
	if x[i] is None:
		x[i] = 0
		q = deque([i])
		while len(q) > 0:
			v = q.popleft()
			if v not in edge:
				break
			for (u, d) in edge[v]:
				if x[u] is None:
					x[u] = x[v] + d
					q.append(u)
				elif x[u] != x[v] + d:
					print('No')
					exit()
print('Yes')


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

def bfs(s):
	que = deque([(0, s)])
	while que:
		(d, v) = que.popleft()
		if visited[v]:
			if d != dist[v]:
				return False
			continue
		visited[v] = True
		dist[v] = d
		for (w, u) in A[v]:
			que.append((d + w, u))
	return True
(N, M) = map(int, input().split())
A = [[] for _ in range(N)]
for _ in range(M):
	(l, r, w) = map(int, input().split())
	l -= 1
	r -= 1
	A[l].append((w, r))
	A[r].append((-w, l))
visited = [0] * N
dist = [0] * N
res = 'Yes'
for i in range(N):
	if visited[i]:
		continue
	f = bfs(i)
	if not f:
		res = 'No'
print(res)


import sys
sys.setrecursionlimit(4100000)

def func(array, arr, d):
	for v in arr:
		if array[v[0]] == None:
			d1 = d + v[1]
			array[v[0]] = d1
			arr1 = dic.get(v[0], [])
			if not func(array, arr1, d1):
				return False
		elif array[v[0]] != d + v[1]:
			return False
	return True
(n, m) = map(int, input().split())
array = [None] * n
dic = {}
for i in range(m):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	dic.setdefault(l, [])
	dic.setdefault(r, [])
	dic[l].append((r, d))
	dic[r].append((l, -d))
for i in range(n):
	if array[i] != None:
		continue
	array[i] = 0
	arr = dic.get(i, [])
	if not func(array, arr, 0):
		print('No')
		sys.exit()
print('Yes')


from sys import exit

class WeightedUnionFind:

	def __init__(self, n):
		self.n = n
		self.parent = [i for i in range(n + 1)]
		self.rank = [0] * (n + 1)
		self.weights = [0] * (n + 1)

	def find(self, x):
		if self.parent[x] == x:
			return x
		nx = self.find(self.parent[x])
		self.weights[x] += self.weights[self.parent[x]]
		self.parent[x] = nx
		return nx

	def unite(self, x, y, d):
		rx = self.find(x)
		ry = self.find(y)
		if rx == ry:
			return
		if self.rank[rx] < self.rank[ry]:
			self.parent[rx] = ry
			self.weights[rx] = d + self.weights[y] - self.weights[x]
		else:
			self.parent[ry] = rx
			self.weights[ry] = -d + self.weights[x] - self.weights[y]
			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.weights[x] - self.weights[y]
(n, m) = map(int, input().split())
wuf = WeightedUnionFind(n)
for _ in range(m):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	if not wuf.same(l, r):
		wuf.unite(l, r, d)
	elif wuf.diff(l, r) != d:
		print('No')
		exit()
print('Yes')


import sys
sys.setrecursionlimit(100000)

class P_UnionFind:

	def __init__(self, n):
		self.p = [i for i in range(n)]
		self.r = [0 for i in range(n)]
		self.d = [0 for i in range(n)]

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

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

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

	def uni(self, x, y, w):
		if self.same(x, y) and self.diff(x, y) != w:
			return False
		w += self.weight(x)
		w -= self.weight(y)
		x = self.root(x)
		y = self.root(y)
		if x == y:
			return
		if self.r[x] < self.r[y]:
			self.p[x] = y
			self.d[x] = -w
		else:
			self.p[y] = x
			self.d[y] = w
			if self.r[x] == self.r[y]:
				self.r[x] += 1

	def same(self, x, y):
		return self.root(x) == self.root(y)
(n, m) = map(int, input().split())
uf = P_UnionFind(n)
d = [-1 for i in range(n)]
d[0] = 0
data = []
for i in range(m):
	(a, b, c) = map(int, input().split())
	if uf.uni(a - 1, b - 1, c) == False:
		print('No')
		exit()
print('Yes')


import sys
from collections import deque
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.readline
(N, M) = [int(x) for x in input().strip().split()]
L = [deque([]) for _ in range(N)]
for m in range(M):
	(l, r, d) = [int(x) for x in input().strip().split()]
	L[l - 1].append((r, d))
	L[r - 1].append((l, -d))
D = [0] * N
F = [False] * N

def dfs(n, d):
	if F[n - 1]:
		if D[n - 1] == d:
			return True
		else:
			return False
	F[n - 1] = True
	D[n - 1] = d
	for (nn, d_) in L[n - 1]:
		if not dfs(nn, d + d_):
			return False
	else:
		return True
for n in range(1, N + 1):
	if not dfs(n, D[n - 1]):
		print('No')
		exit()
else:
	print('Yes')


import sys
sys.setrecursionlimit(10001000)

class UnionFindWeighted:

	def __init__(self, n):
		self.n = n
		self.parents = [i for i in range(n)]
		self.ranks = [0] * n
		self.sizes = [1] * n
		self.weights = [0] * n

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

	def unite(self, x, y, w):
		rx = self.find(x)
		ry = self.find(y)
		wx = self.weight(x)
		wy = self.weight(y)
		if rx == ry:
			return
		if self.ranks[rx] > self.ranks[ry]:
			(rx, ry) = (ry, rx)
			(wx, wy) = (wy, wx)
			w *= -1
			print('a')
		self.parents[rx] = ry
		self.sizes[ry] += self.sizes[rx]
		self.weights[rx] = wy - wx - w
		if self.ranks[rx] == self.ranks[ry]:
			self.ranks[rx] += 1

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

	def members(self, x):
		root = self.find(x)
		return {i for i in range(self.n) if self.find(i) == root}

	def size(self, x):
		root = self.find(x)
		return self.sizes[root]

	def roots(self):
		return {i for (i, x) in enumerate(self.parents) if i == x}

	def group_count(self):
		return len(self.roots())

	def all_group_members(self):
		return {r: self.members(r) for r in self.roots()}

	def weight(self, x):
		_ = self.find(x)
		return self.weights[x]

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

	def __str__(self):
		return '\n'.join(('{}: {}'.format(r, self.members(r)) for r in self.roots()))
(n, m) = map(int, input().split())
uf = UnionFindWeighted(n)
for _ in range(m):
	(a, b, w) = map(int, input().split())
	a -= 1
	b -= 1
	if uf.same(a, b):
		if uf.diff(a, b) != w:
			print('No')
			exit()
	else:
		uf.unite(a, b, w)
print('Yes')


class WeightedUnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n)]
		self.rank = [0 for i in range(n)]
		self.diff_weight = [0 for i in range(n)]

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

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

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

	def unite(self, x, y, w):
		w += self.weight(x)
		w -= self.weight(y)
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return False
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
			w = -w
			self.diff_weight[x] = w
		elif self.rank[y] < self.rank[x]:
			self.par[y] = x
			self.diff_weight[y] = w
		else:
			self.par[y] = x
			self.diff_weight[y] = w
			self.rank[x] += 1
		return True
(N, M) = map(int, input().split())
wuf = WeightedUnionFind(N)
for i in range(M):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	if wuf.find(l) == wuf.find(r):
		if wuf.diff(l, r) != d:
			print('No')
			break
	wuf.unite(l, r, d)
else:
	print('Yes')


class WeightedUnionFind:

	def __init__(self, size):
		self.parent = [i for i in range(size)]
		self.rank = [0] * size
		self.diff_weight = [0] * size

	def find(self, x):
		if self.parent[x] == x:
			return x
		r = self.find(self.parent[x])
		self.diff_weight[x] += self.diff_weight[self.parent[x]]
		self.parent[x] = r
		return r

	def unite(self, x, y, w):
		w += self.weight(x) - self.weight(y)
		(x, y) = (self.find(x), self.find(y))
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			(x, y) = (y, x)
			w = -w
		if self.rank[x] == self.rank[y]:
			self.rank[x] += 1
		self.parent[y] = x
		self.diff_weight[y] = w

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

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

	def diff(self, x, y):
		return self.weight(y) - self.weight(x)
(N, M) = map(int, input().split())
uf = WeightedUnionFind(N)
for _ in range(M):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	if uf.same(l, r) and uf.diff(l, r) != d:
		print('No')
		exit()
	uf.unite(l, r, d)
print('Yes')


class WeightedUnionFind:

	def __init__(self, n):
		self.par = [i for i in range(n)]
		self.rank = [0 for i in range(n)]
		self.diff_weight = [0 for i in range(n)]

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

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

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

	def unite(self, x, y, w):
		w += self.weight(x)
		w -= self.weight(y)
		x = self.find(x)
		y = self.find(y)
		if x == y:
			return
		if self.rank[x] < self.rank[y]:
			self.par[x] = y
			w = -w
			self.diff_weight[x] = w
		elif self.rank[y] < self.rank[x]:
			self.par[y] = x
			self.diff_weight[y] = w
		else:
			self.par[y] = x
			self.rank[x] += 1
			self.diff_weight[y] = w
(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.find(L) == UF.find(R):
		if UF.diff(L, R) != D:
			print('No')
			break
	else:
		UF.unite(L, R, D)
else:
	print('Yes')


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

def bfs(s):
	q = deque([s])
	visited[s] = True
	while q:
		v = q.popleft()
		for (nv, d) in G[v]:
			if visited[nv]:
				if dist[v] + d != dist[nv]:
					print('No')
					exit()
			else:
				visited[nv] = True
				dist[nv] = dist[v] + d
				q.append(nv)
(N, M) = map(int, input().split())
G = [[] for _ in range(N)]
for _ in range(M):
	(L, R, D) = map(int, input().split())
	G[L - 1].append((R - 1, D))
	G[R - 1].append((L - 1, -D))
visited = [False] * N
dist = [0] * N
for i in range(N):
	if not visited[i]:
		bfs(i)
print('Yes')


import sys
sys.setrecursionlimit(100000)

def depth_dp(v):
	if point[v] == float('inf'):
		point[v] = 0
	flag[v] = True
	for e in E[v]:
		if point[e[0]] == float('inf'):
			point[e[0]] = point[v] + e[1]
		elif point[e[0]] != point[v] + e[1]:
			return False
	for e in E[v]:
		if not flag[e[0]]:
			if not depth_dp(e[0]):
				return False
	return True
(N, M) = list(map(int, input().split()))
E = [[] for _ in range(N)]
flag = [False] * N
ans = True
point = [float('inf')] * 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))
for i in range(N):
	if not flag[i]:
		if not depth_dp(i):
			ans = False
			break
if ans:
	print('Yes')
else:
	print('No')


import sys
sys.setrecursionlimit(10 ** 6)
(N, M) = map(int, sys.stdin.readline().split())
G = [[] for i in range(N)]
for i in range(M):
	(l, r, q) = map(int, sys.stdin.readline().split())
	G[l - 1].append((r - 1, q))
	G[r - 1].append((l - 1, -q))
R = [None] * N

def dfs(u):
	global R, G
	for (w, d) in G[u]:
		if R[w] is None:
			R[w] = R[u] + d
			if not dfs(w):
				return False
		elif R[w] != R[u] + d:
			return False
	return True
flag = True
for i in range(N):
	if R[i] is None:
		R[i] = 0
		flag &= dfs(i)
if flag:
	print('Yes')
else:
	print('No')


from collections import Counter, defaultdict, deque
from heapq import heappop, heappush, heapify
import sys, bisect, math, itertools, fractions, pprint
sys.setrecursionlimit(10 ** 8)
mod = 10 ** 9 + 7
mod2 = 998244353
INF = float('inf')

def inp():
	return int(sys.stdin.readline())

def inpl():
	return list(map(int, sys.stdin.readline().split()))

def inpln(n):
	return list((int(sys.stdin.readline()) for i in range(n)))

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]

def chk(a, b, c):
	return True if uf.diff(a, b) == c else False
(n, m) = inpl()
z = [-1] * n
uf = WeightedUnionFind(n)
for i in range(m):
	(a, b, c) = inpl()
	a -= 1
	b -= 1
	if uf.same(a, b):
		if not chk(a, b, c):
			print('No')
			quit()
	else:
		uf.union(a, b, c)
print('Yes')


def find(x, U, r, w):
	if x == U[x]:
		return (x, w[x])
	else:
		k = find(U[x], U, r, w)
		w[x] += w[U[x]]
		U[x] = k[0]
		return (U[x], w[x])

def merge(a, b, U, r, w, w_add):
	a = find(a, U, r, w)[0]
	b = find(b, U, r, w)[0]
	if a == b:
		return
	U[b] = a
	r[a] = max(r[a], r[b] + 1)
	w[b] += w_add
	return
(N, M) = map(int, input().split())
U = [i for i in range(N)]
w = [0 for _ in range(N)]
r = [0 for _ in range(N)]
ans = True
for _ in range(M):
	(L, R, D) = map(int, input().split())
	L -= 1
	R -= 1
	t1 = find(L, U, r, w)
	t2 = find(R, U, r, w)
	if t1[0] == t2[0] and (not t2[1] - t1[1] == D):
		ans = False
		break
	if not t1[0] == t2[0]:
		D -= t2[1] - t1[1]
		if r[L] < r[R]:
			(L, R) = (R, L)
			D = -D
		merge(L, R, U, r, w, D)
print('Yes' if ans else 'No')


import sys
sys.setrecursionlimit(200002)
(n, m) = map(int, input().split())
a = [[] for i in range(n)]
for i in range(m):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	a[l].append((r, d))
	a[r].append((l, -d))
bio = [None for i in range(n)]

def dfs(x):
	for (y, d) in a[x]:
		if bio[y] is None:
			bio[y] = bio[x] + d
			if not dfs(y):
				return False
		elif bio[y] != bio[x] + d:
			return False
	return True
for i in range(n):
	if bio[i] is None:
		bio[i] = 0
		if not dfs(i):
			print('No')
			exit(0)
print('Yes')


(N, M) = map(int, input().split())
A = [[] for i in range(N)]
for i in range(M):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	A[l].append([r, d])
	A[r].append([l, -d])
ans = 'Yes'
distance = ['#' for i in range(N)]
flg = 0
for i in range(N):
	if flg:
		break
	if distance[i] != '#':
		continue
	distance[i] = 0
	stack = [i]
	while stack:
		now = stack.pop()
		for (to, d) in A[now]:
			if distance[to] == '#':
				distance[to] = distance[now] + d
				stack.append(to)
			elif distance[to] != distance[now] + d:
				ans = 'No'
				stack = []
				flg = 1
				break
print(ans)


import sys
from collections import deque
input = sys.stdin.buffer.readline
(N, M) = map(int, input().split())
adj = [[] for _ in range(N + 1)]
for _ in range(M):
	(l, r, d) = map(int, input().split())
	adj[l].append((r, d))
	adj[r].append((l, -d))
seen = ['!'] * (N + 1)
for i in range(1, N + 1):
	if seen[i] == '!':
		que = deque()
		seen[i] = 0
		que.append(i)
		while que:
			v = que.popleft()
			for (u, d) in adj[v]:
				if seen[u] == '!':
					seen[u] = seen[v] + d
					que.append(u)
				elif seen[v] + d != seen[u]:
					print('No')
					exit()
print('Yes')


import sys
from collections import defaultdict
sys.setrecursionlimit(1000000)
(N, M) = map(int, sys.stdin.readline().split())
E = defaultdict(list)
for _ in range(M):
	(l, r, d) = map(int, sys.stdin.readline().split())
	l -= 1
	r -= 1
	E[l].append((r, d))
	E[r].append((l, -d))
xs = [None] * N

def dfs(i, x):
	xs[i] = x
	(mi, ma) = (x, x)
	for (j, d) in E[i]:
		if xs[j] is None:
			res = dfs(j, x + d)
			if res is None:
				return None
			else:
				(mi2, ma2) = res
				mi = min(mi2, mi)
				ma = max(ma2, ma)
		elif xs[j] - x != d:
			return None
	return (mi, ma)
for i in range(N):
	if xs[i] is None:
		res = dfs(i, 0)
		if res is None:
			break
		else:
			(mi, ma) = res
			if ma - mi > 1000000000.0:
				break
else:
	print('Yes')
	sys.exit()
print('No')


(n, m) = map(int, input().split())
par = [i for i in range(n)]
ws = [0 for _ in range(n)]

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

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

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

def merge(x, y, w):
	if root(x) == root(y):
		if diff(x, y) != w:
			print('No')
			exit()
		else:
			return
	else:
		wy = weight(y)
		wx = weight(x)
		x = root(x)
		y = root(y)
		if w + wy >= wx:
			par[x] = y
			ws[x] = w + wy - wx
		else:
			par[y] = x
			ws[y] = wx - w - wy
for _ in range(m):
	(x, y, z) = map(int, input().split())
	x -= 1
	y -= 1
	merge(x, y, z)
print('Yes')


import sys
sys.setrecursionlimit(1000000)
(n, m) = map(int, input().split())
a = [[] for _ in range(n)]
for _ in range(m):
	(l, r, d) = map(int, input().split())
	a[l - 1].append((r - 1, d))
	a[r - 1].append((l - 1, -d))
x = [None for _ in range(n)]

def check(y):
	for (z, d) in a[y]:
		if x[z] is None:
			x[z] = x[y] + d
			if not check(z):
				return False
		elif x[z] != x[y] + d:
			return False
	return True
for i in range(n):
	if x[i] is None:
		x[i] = 0
		if not check(i):
			print('No')
			exit(0)
print('Yes')


import sys
sys.setrecursionlimit(10 ** 6)
(n, m) = map(int, input().split())
g = [[] for _ in range(n)]
indeg = [0] * n
touch = [0] * n
for _ in range(m):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	touch[l] = 1
	touch[r] = 1
	g[l].append((r, d))
	indeg[r] += 1
if m == 0:
	print('Yes')
	exit()
entered = False
for i in range(n):
	if indeg[i] == 0 and touch[i] == 1:
		vis = [False] * n
		entered = True
		dist = [-1] * n
		dist[i] = 0

		def dfs(u):
			vis[u] = 1
			for (v, wt) in g[u]:
				if dist[v] == -1:
					dist[v] = dist[u] + wt
				elif dist[v] != dist[u] + wt:
					print('No')
					exit()
				if vis[v] == False:
					dfs(v)
		dfs(i)
if entered == False:
	print('No')
else:
	print('Yes')


from collections import Counter, defaultdict
import sys
sys.setrecursionlimit(10 ** 5 + 10)
input = sys.stdin.readline
from math import factorial
import heapq, bisect
import math

def calc(A, B, C, now_t):
	ans = A * now_t + B * math.sin(C * now_t * math.pi)
	return ans

def main():
	(num, hint_num) = map(int, input().split())
	data = [list(map(int, input().split())) for i in range(hint_num)]
	graph_data = defaultdict(set)
	dist_data = defaultdict(int)
	for i in range(hint_num):
		(l, r, d) = data[i]
		graph_data[l].add(r)
		graph_data[r].add(l)
		dist_data[l, r] = d
		dist_data[r, l] = -1 * d
	position = ['x' for i in range(num + 1)]
	flg = 1
	for i in range(1, num + 1):
		if position[i] != 'x':
			continue
		position[i] = 0
		now_set = set()
		next_set = set()
		now_set.add(i)
		while len(now_set) > 0:
			for now_ele in now_set:
				for next_ele in graph_data[now_ele]:
					length = dist_data[now_ele, next_ele]
					if position[next_ele] == 'x':
						position[next_ele] = position[now_ele] + length
						next_set.add(next_ele)
					elif position[next_ele] != position[now_ele] + length:
						flg = 0
						break
			now_set = next_set
			next_set = set()
	if flg:
		print('Yes')
	else:
		print('No')
main()


(n, m) = map(int, input().split())
par = [i for i in range(n)]
diff = [0] * n

def find(x):
	if par[x] == x:
		return (x, 0)
	else:
		(a, b) = find(par[x])
		par[x] = a
		diff[x] += b
		return (a, diff[x])

def unite(x, y, z):
	(s, ws) = find(x)
	(t, wt) = find(y)
	if s == t:
		if ws - wt == z:
			pass
		else:
			print('No')
			exit(0)
	elif ws < z + wt:
		par[s] = t
		diff[s] = z + wt - ws
	else:
		par[t] = s
		diff[t] = ws - z - wt
for _ in range(m):
	(l, r, d) = map(int, input().split())
	unite(l - 1, r - 1, d)
print('Yes')


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 5 + 1)

def dfs(p):
	for edge in g[p]:
		if x[edge[0]] is not None:
			if x[edge[0]] - x[p] != edge[1]:
				print('No')
				exit()
		else:
			x[edge[0]] = x[p] + edge[1]
			dfs(edge[0])
(n, m) = map(int, input().split())
g = [[] for i in range(n)]
for i in range(m):
	(u, v, c) = map(int, input().split())
	g[u - 1].append((v - 1, c))
	g[v - 1].append((u - 1, -c))
x = [None] * n
for i in range(n):
	if x[i] == None:
		x[i] = 0
		dfs(i)
print('Yes')


class DSUWeighted:

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

	def leader(self, a):
		x = a
		order = [x]
		while self.par_size[x] >= 0:
			x = self.par_size[x]
			order.append(x)
		for s in order[:-1][::-1]:
			self.wt[s] += self.wt[self.par_size[s]]
			self.par_size[s] = x
		return x

	def same(self, a, b):
		return self.leader(a) == self.leader(b)

	def merge(self, a, b, w):
		x = self.leader(a)
		y = self.leader(b)
		w += self.wt[a] - self.wt[b]
		if x == y:
			return x
		if -self.par_size[x] < -self.par_size[y]:
			(x, y) = (y, x)
			w = -w
		self.par_size[x] += self.par_size[y]
		self.par_size[y] = x
		self.wt[y] = w
		return x

	def diff(self, x, y):
		return self.wt[y] - self.wt[x]
import sys
input = sys.stdin.buffer.readline
(N, M) = map(int, input().split())
uf = DSUWeighted(N)
for _ 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')
			break
	else:
		uf.merge(l - 1, r - 1, d)
else:
	print('Yes')


(n, m) = map(int, input().split())
ed = [[] for _ in range(n)]
v = [None] * n
for _ in range(m):
	(l, r, d) = map(int, input().split())
	ed[l - 1].append((r - 1, d))
	ed[r - 1].append((l - 1, -d))
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)
				elif 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')


(n, m) = (int(x) for x in input().split())
p = [(i, 0) for i in range(n)]

def check(i):
	(j, d) = p[i]
	if j != i:
		(ii, dd) = check(j)
		p[i] = (ii, d + dd)
	return p[i]
f = True
for _ in range(m):
	(l, r, d) = (int(x) for x in input().split())
	l -= 1
	r -= 1
	(li, ld) = check(l)
	(ri, rd) = check(r)
	if li != ri:
		t = d + ld - rd
		if t >= 0:
			p[ri] = (li, t)
		else:
			p[li] = (ri, -t)
	elif rd - ld != d:
		f = False
		break
print('Yes' if f else 'No')


def check(si, xs, checked):
	q = [si]
	while q:
		i = q.pop()
		xi = xs[i]
		for (j, d) in links[i]:
			if checked[j]:
				continue
			if j not in xs:
				xs[j] = xi + d
			elif xi + d != xs[j]:
				return False
			q.append(j)
		checked[i] = True
	return True

def solve():
	checked = [False] * n
	for i in range(n):
		if not checked[i]:
			xs = {}
			xs[i] = 0
			if not check(i, xs, checked):
				return False
	return True
(n, m) = map(int, input().split())
links = [set() for _ in range(n)]
for _ in range(m):
	(l, r, d) = map(int, input().split())
	l -= 1
	r -= 1
	links[l].add((r, d))
	links[r].add((l, -d))
print('Yes' if solve() else '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 is_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 = WeightedUnionFind(N + 1)
ans = 'Yes'
for i in range(M):
	(L, R, D) = map(int, input().split())
	if wuf.is_same(L, R):
		if wuf.diff(L, R) != D:
			ans = 'No'
			break
	else:
		wuf.union(L, R, D)
print(ans)


from collections import deque
(n, m) = map(int, input().split())
edges = [{} for i in range(n + 1)]
for i in range(m):
	(l, r, d) = map(int, input().split())
	edges[l][r] = d
	edges[r][l] = d * -1
remains = set(range(1, n + 1))
deq = deque()
min_ = -1 * 10 ** 10
xs = [min_] * (n + 1)
while len(remains) > 0:
	deq.append(remains.pop())
	while len(deq) > 0:
		tmp = deq.popleft()
		if xs[tmp] == min_:
			xs[tmp] = 0
		tmp_x = xs[tmp]
		edge = edges[tmp]
		for (key, val) in edge.items():
			if xs[key] == min_:
				xs[key] = tmp_x + val
				deq.append(key)
				remains.remove(key)
			elif xs[key] != tmp_x + val:
				print('No')
				exit()
print('Yes')


(N, M) = map(int, input().split())
edge = [[] for _ in range(N + 1)]
for _ in range(M):
	(l, r, d) = map(int, input().split())
	edge[l].append([r, d])
	edge[r].append([l, -d])
G = [None] * (N + 1)
ok = True
stack = []
for x in range(1, N + 1):
	if G[x] is not None:
		continue
	G[x] = 0
	stack = [x]
	while stack:
		v = stack.pop()
		for (to, d) in edge[v]:
			if G[to] is None:
				G[to] = G[v] + d
				stack.append(to)
			elif G[to] != G[v] + d:
				ok = False
				break
	if ok == False:
		break
print('Yes' if ok else 'No')


def main():
	from collections import deque, defaultdict
	(n, m) = map(int, input().split())
	g = [[] for _ in range(n + 1)]
	ref = defaultdict(list)
	q = deque([])
	visited = set()
	inf = 10 ** 10
	dist = [-inf] * (n + 1)
	for i in range(m):
		(a, b, k) = map(int, input().split())
		g[a].append(b)
		g[b].append(a)
		ref[a, b] = k

	def dfs(u):
		q.append(u)
		while q:
			v = q.pop()
			visited.add(v)
			for x in g[v]:
				if x not in visited:
					if ref[v, x] != []:
						y = ref.get((v, x))
						if dist[x] == -inf:
							dist[x] = dist[v] + y
						elif dist[x] != dist[v] + y:
							print('No')
							exit()
					else:
						y = ref.get((x, v))
						if dist[x] == -inf:
							dist[x] = dist[v] - y
						elif dist[v] != dist[x] + y:
							print('No')
							exit()
					q.append(x)
	for i in range(1, n + 1):
		if i not in visited:
			dist[i] = 1
			dfs(i)
	print('Yes')
main()


from collections import *

class POTENTIAL_UNION_FIND(object):

	def __init__(self, n):
		self.parent = [-1 for i in range(n)]
		self.diff_p = [0 for i in range(n)]

	def root(self, x):
		if self.parent[x] < 0:
			return x
		else:
			rx = self.root(self.parent[x])
			self.diff_p[x] += self.diff_p[self.parent[x]]
			self.parent[x] = rx
			return rx

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

	def merge(self, x, y, dxy):
		rx = self.root(x)
		ry = self.root(y)
		dxy += self.diff_p[x] - self.diff_p[y]
		(x, y) = (rx, ry)
		if x == y:
			return False
		if self.parent[x] > self.parent[y]:
			(x, y, dxy) = (y, x, -dxy)
		self.parent[x] += self.parent[y]
		self.parent[y] = x
		self.diff_p[y] = dxy
		return True

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

	def diff(self, x, y):
		if self.root(x) == self.root(y):
			return self.diff_p[y] - self.diff_p[x]
		else:
			return None
(n, m) = map(int, input().split())
u = POTENTIAL_UNION_FIND(n)
d = defaultdict(int)
for i in range(m):
	(a, b, c) = map(int, input().split())
	d[a - 1, b - 1] = c
	u.merge(a - 1, b - 1, c)
for (k, v) in d.items():
	if v != u.diff(*k):
		print('No')
		exit()
print('Yes')


from collections import deque
(n, m) = map(int, input().split())
inf = 10 ** 10
edge = [[] for i in range(n)]
x = [inf] * n
for i in range(m):
	(l, r, d) = map(int, input().split())
	edge[l - 1].append((r - 1, d))
	edge[r - 1].append((l - 1, -d))
for i in range(n):
	if x[i] == inf:
		x[i] = 0
		q = deque([i])
		while len(q) != 0:
			now = q.popleft()
			for e in edge[now]:
				if x[e[0]] == inf:
					x[e[0]] = x[now] + e[1]
					q.append(e[0])
				elif x[e[0]] - x[now] != e[1]:
					print('No')
					exit()
print('Yes')


class UnionFind:

	def __init__(self, size):
		self.parent = [-1 for i in range(size)]
		self.diff_potential = [0 for i in range(size)]

	def root(self, x):
		if self.parent[x] < 0:
			return x
		else:
			rx = self.root(self.parent[x])
			self.diff_potential[x] += self.diff_potential[self.parent[x]]
			self.parent[x] = rx
			return rx

	def merge(self, x, y, diffxy):
		diffxy = self.diff_potential[x] + diffxy - self.diff_potential[y]
		x = self.root(x)
		y = self.root(y)
		if x == y:
			return False
		if self.parent[x] > self.parent[y]:
			(x, y) = (y, x)
			diffxy = -diffxy
		self.parent[x] += self.parent[y]
		self.parent[y] = x
		self.diff_potential[y] = diffxy
		return True

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

	def diff(self, x, y):
		if self.root(x) == self.root(y):
			return self.diff_potential[y] - self.diff_potential[x]
		else:
			return None

	def size(self, x):
		return -self.parent[self.root(x)]
(n, m) = list(map(int, input().split()))
uf = UnionFind(n)
ans = True
for i in range(m):
	(l, r, d) = list(map(int, input().split()))
	l -= 1
	r -= 1
	if uf.issame(l, r):
		ans = d == uf.diff(l, r)
	else:
		uf.merge(l, r, d)
	if ans == False:
		break
if ans == False:
	print('No')
else:
	print('Yes')


import sys
input = sys.stdin.readline

def main():

	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)
	(n, m) = map(int, input().split())
	par = [-1] * n
	wei = [0] * n
	for _ in range(m):
		(l, r, d) = map(int, input().split())
		l -= 1
		r -= 1
		if same(l, r):
			if diff(l, r) != d:
				print('No')
				sys.exit()
		else:
			unite(l, r, d)
	print('Yes')
main()


import sys
sys.setrecursionlimit(1000000)
(N, M) = map(int, input().split())

class UnionFind:

	def __init__(self, n):
		self.n = n
		self.root = [-1] * (n + 1)
		self.rnk = [0] * (n + 1)

	def Find_Root(self, x):
		if self.root[x] < 0:
			return x
		else:
			self.root[x] = self.Find_Root(self.root[x])
			return self.root[x]

	def Unite(self, x, y):
		x = self.Find_Root(x)
		y = self.Find_Root(y)
		if x == y:
			return
		elif self.rnk[x] > self.rnk[y]:
			self.root[x] += self.root[y]
			self.root[y] = x
		else:
			self.root[y] += self.root[x]
			self.root[x] = y
			if self.rnk[x] == self.rnk[y]:
				self.rnk[y] += 1

	def isSameGroup(self, x, y):
		return self.Find_Root(x) == self.Find_Root(y)

	def Count(self, x):
		return -self.root[self.Find_Root(x)]
union = UnionFind(N - 1)
graph = [[] for _ in range(N)]
for _ in range(M):
	(a, b, d) = map(int, input().split())
	graph[a - 1].append((d, b - 1))
	graph[b - 1].append((-d, a - 1))
	union.Unite(a - 1, b - 1)
roots = set()
for i in range(N):
	roots.add(union.Find_Root(i))
NUM = [None for _ in range(N)]
checked = [False for _ in range(N)]

def dfs(p, NUM, ans):
	x = NUM[p]
	for (d, q) in graph[p]:
		if NUM[q] is None:
			NUM[q] = x + d
		elif NUM[q] != x + d:
			ans = False
			return ans
		if checked[q]:
			continue
		checked[q] = True
		ans = dfs(q, NUM, ans)
	return ans
ans = True
for r in roots:
	NUM[r] = 0
	ok = dfs(r, NUM, True)
	ans = ans and ok
if ans:
	print('Yes')
else:
	print('No')


class WeighttedUnionFind:

	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())
wuf = WeighttedUnionFind(N)
for _ in range(M):
	(l, r, d) = map(int, input().split())
	if not wuf.same(l, r):
		wuf.union(l, r, d)
	elif wuf.diff(l, r) != d:
		print('No')
		exit()
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)
ans = True
for i in range(m):
	(l, r, d) = map(int, input().split())
	if uf.same(l, r) == False:
		uf.union(l, r, d)
	elif abs(uf.diff(l, r)) != d:
		ans = False
		break
print('Yes' if ans else 'No')


from collections import deque

def main():
	(n, m) = map(int, input().split())
	graph = [[] for i in range(n)]
	for _ in range(m):
		(l, r, d) = map(int, input().split())
		graph[l - 1] += [(r - 1, d)]
		graph[r - 1] += [(l - 1, -d)]
	que = deque()
	lines = [None] * n
	for i in range(n):
		if lines[i] is not None:
			continue
		lines[i] = 0
		que.append(i)
		while que:
			cur = que.popleft()
			for (nxt, cost) in graph[cur]:
				if lines[nxt] is None:
					lines[nxt] = lines[cur] + cost
					que.append(nxt)
				elif lines[nxt] != lines[cur] + cost:
					return 'No'
	return 'Yes'
print(main())


import sys
sys.setrecursionlimit(10 ** 5)

def f(hito, zahyo):
	x[hito] = zahyo
	for tsugi in links[hito]:
		if x[tsugi[0]] == None:
			f(tsugi[0], zahyo + tsugi[1])
		elif x[tsugi[0]] != zahyo + tsugi[1]:
			print('No')
			exit()
(N, M) = map(int, input().split())
links = [[] for _ in range(N + 1)]
for _ in range(M):
	(l, r, d) = map(int, input().split())
	links[l].append([r, d])
	links[r].append([l, -d])
x = [None] * (N + 1)
for i in range(1, N + 1):
	if x[i] == None:
		f(i, 0)
print('Yes')


import heapq
(n, m) = map(int, input().split())
graph = [[] for i in range(n)]
for i in range(m):
	(l, r, d) = map(int, input().split())
	graph[l - 1].append((r - 1, d))
	graph[r - 1].append((l - 1, -d))
visited = [False for i in range(n)]
pos = [0 for i in range(n)]
for i in range(n):
	if visited[i]:
		continue
	hq = [(i, 0)]
	while hq:
		(v, p) = heapq.heappop(hq)
		if visited[v]:
			if p != pos[v]:
				print('No')
				exit()
			continue
		visited[v] = True
		pos[v] = p
		for (nv, d) in graph[v]:
			if visited[nv]:
				if pos[nv] != p + d:
					print('No')
					exit()
				continue
			heapq.heappush(hq, (nv, p + d))
print('Yes')


import sys
sys.setrecursionlimit(200002)
(n, m) = list(map(int, input().split()))
g = [[] for _ in range(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))
ds = [None for _ in range(n + 1)]

def check(v):
	for (next_v, d) in g[v]:
		if ds[next_v] is None:
			ds[next_v] = ds[v] + d
			if check(next_v) is False:
				return False
		elif not ds[next_v] - ds[v] == d:
			return False
	return True
valid = True
for v in range(n):
	if ds[v] is None:
		ds[v] = 0
	if check(v) is False:
		valid = False
		break
if valid:
	print('Yes')
else:
	print('No')


import heapq
(N, M) = map(int, input().split())
INF = 10 ** 9 + 1
(G, dist) = ([[] for i in range(N)], [INF for j in range(N)])
(check, p) = ([0 for k in range(N)], [-1 for l in range(N)])

def dijkstra(s):
	(dist[s], pq) = (0, [])
	heapq.heappush(pq, (0, s))
	while len(pq) != 0:
		u = heapq.heappop(pq)
		check[u[1]] = 2
		if dist[u[1]] < u[0]:
			continue
		for v in G[u[1]]:
			if check[v[0]] != 2:
				if dist[u[1]] + v[1] < dist[v[0]]:
					(dist[v[0]], check[v[0]]) = (dist[u[1]] + v[1], 1)
					heapq.heappush(pq, (dist[v[0]], v[0]))

def main():
	data = []
	for i in range(M):
		(l, r, d) = map(int, input().split())
		G[l - 1].append((r - 1, d))
		p[r - 1] = l - 1
		data.append((l, r, d))
	for i in range(N):
		if p[i] == -1:
			dijkstra(i)
	for i in range(M):
		(l, r, d) = data[i]
		if dist[r - 1] - dist[l - 1] != d:
			print('No')
			break
	else:
		print('Yes')
main()


import sys
input = sys.stdin.buffer.readline
from collections import defaultdict

def getlist():
	return list(map(int, input().split()))

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)
		self.size = [1] * (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 same_check(self, x, y):
		return self.find(x) == self.find(y)

	def union(self, x, y, w):
		rx = self.find(x)
		ry = self.find(y)
		if self.rank[rx] < self.rank[ry]:
			if self.same_check(x, y) != True:
				self.size[y] += self.size[x]
				self.size[x] = 0
			self.par[rx] = ry
			self.weight[rx] = w - self.weight[x] + self.weight[y]
		else:
			if self.same_check(x, y) != True:
				self.size[x] += self.size[y]
				self.size[y] = 0
			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 size(self, x):
		x = self.find(x)
		return self.size(x)

	def diff(self, x, y):
		if self.same_check(x, y) == True:
			return self.weight[x] - self.weight[y]
		else:
			print('inf')

def main():
	(N, M) = getlist()
	judge = 'Yes'
	UF = WeightedUnionFind(N)
	for i in range(M):
		(L, R, D) = getlist()
		if UF.same_check(L - 1, R - 1):
			if UF.diff(L - 1, R - 1) != D:
				judge = 'No'
				break
		else:
			UF.union(L - 1, R - 1, D)
	print(judge)
main()


def main():
	for _ in range(M):
		(l, r, d) = map(int, input().split())
		pl = find(l)
		pr = find(r)
		if pl == pr and x[r] - x[l] != d:
			print('No')
			exit()
		else:
			p[pr] = pl
			x[pr] = x[l] + d - x[r]

def find(i):
	if p[i] == i:
		return i
	(p[i], x[i]) = (find(p[i]), x[i] + x[p[i]])
	return p[i]
(N, M) = map(int, input().split())
p = list(range(N + 1))
x = [0] * (N + 1)
main()
print('Yes')


(n, m) = map(int, input().split())
xs = [tuple(map(int, input().split())) for _ in range(m)]
union = {x: (x, 0) for x in range(1, n + 1)}

def root(n):
	if union[n][0] == n:
		return union[n]
	(n1, d1) = union[n]
	(n2, d2) = root(n1)
	union[n] = (n2, d2 + d1)
	return union[n]
for (l, r, d) in xs:
	(n1, d1) = root(l)
	(n2, d2) = root(r)
	if n1 != n2:
		union[n2] = (n1, d + d1 - d2)
	elif d != d2 - d1:
		print('No')
		break
else:
	print('Yes')


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

def judge(W, D, visit, i):
	visit[i] = True
	for (j, d) in W[i]:
		if D[j] is None:
			D[j] = D[i] + d
		elif D[i] + d != D[j]:
			return True
		if visit[j]:
			continue
		if judge(W, D, visit, j):
			return True
	return False

def main():
	W = [[] for _ in range(N)]
	for (l, r, d) in LRD:
		W[l - 1].append((r - 1, d))
		W[r - 1].append((l - 1, -d))
	D = [None] * N
	visit = [False] * N
	for i in range(N):
		if visit[i]:
			continue
		D[i] = 0
		if judge(W, D, visit, i):
			print('No')
			return
	print('Yes')
main()


from collections import defaultdict, deque
(n, m) = map(int, input().split())
edge = [[] for i in range(n)]
for i in range(m):
	(l, r, d) = map(int, input().split())
	edge[l - 1].append((r - 1, d))
	edge[r - 1].append((l - 1, -d))
dist = [0] * n
visited = [False] * n
for i in range(n):
	if visited[i]:
		continue
	q = deque()
	q.append((i, 0))
	while q:
		(to, d) = q.popleft()
		if visited[to]:
			if dist[to] != d:
				print('No')
				exit()
		else:
			visited[to] = True
			dist[to] = d
			for (ind, j) in edge[to]:
				q.append((ind, d + j))
print('Yes')


import sys
sys.setrecursionlimit(10 ** 6)

class Impossible(ValueError):
	pass

def main():
	(n, m) = map(int, input().split())
	lrds = []
	for i in range(m):
		(l, r, d) = map(int, input().split())
		lrds.append((l - 1, r - 1, d))
	adj = [[] for i in range(n)]
	parents = [i for i in range(n)]
	for i in range(m):
		(l, r, d) = lrds[i]
		union(parents, l, r)
		adj[l].append((r, d))
		adj[r].append((l, -d))
	ds = set()
	for i in range(n):
		ds.add(find(parents, i))
	pos = [None for i in range(n)]
	try:
		for i in ds:
			pos[i] = 0
			dfs(adj, pos, i)
		print('Yes')
	except Impossible:
		print('No')

def dfs(adj, pos, x):
	for (y, d) in adj[x]:
		if pos[y] is None:
			pos[y] = pos[x] + d
			dfs(adj, pos, y)
		elif pos[y] != pos[x] + d:
			raise Impossible

def find(p, x):
	if p[x] != x:
		p[x] = find(p, p[x])
	return p[x]

def union(p, x, y):
	p[find(p, y)] = find(p, x)
main()


import sys
(n, m) = map(int, input().split())
lrd = [list(map(int, input().split())) for i in range(m)]
x = ['a'] * (n + 1)
R = [[] for i in range(n + 1)]
L = [[] for i in range(n + 1)]
for u in lrd:
	(l, r, d) = u
	R[l].append([r, d])
	L[r].append([l, d])
for i in range(1, n + 1):
	if x[i] == 'a':
		x[i] = 0
		que = [i]
		while que:
			h = que.pop()
			for u in R[h]:
				(r, d) = u
				if x[r] == 'a':
					x[r] = x[h] + d
					que.append(r)
				elif x[r] == x[h] + d:
					continue
				else:
					print('No')
					sys.exit()
			for u in L[h]:
				(l, d) = u
				if x[l] == 'a':
					x[l] = x[h] - d
					que.append(l)
				elif x[l] == x[h] - d:
					continue
				else:
					print('No')
					sys.exit()
print('Yes')


import sys

def input():
	return sys.stdin.readline().strip()
(N, M) = map(int, input().split())
P = [list(map(int, input().split())) for i in range(M)]
inf = 10 ** 15
c = [[] for i in range(N)]
for (i, j, w) in P:
	c[i - 1].append((j - 1, w))
	c[j - 1].append((i - 1, -w))
d = [inf] * N
v = [0] * N
a = 0
import sys
sys.setrecursionlimit(10 ** 7)

def dfs(p, v, d):
	for (n, w) in c[p]:
		if v[n] == 0:
			d[n] = d[p] + w
			v[n] = 1
			if dfs(n, v, d) == -1:
				return -1
		elif d[p] + w != d[n]:
			return -1
	return 0
s = 0
while True:
	d[s] = 0
	v[s] = 1
	a = dfs(s, v, d)
	if a < 0:
		break
	try:
		s = d.index(inf, s)
	except ValueError:
		break
print(['Yes', 'No'][a])


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 7)
(N, M) = map(int, input().split())
L = [[] for i in range(N + 1)]
D = dict()
for i in range(M):
	(l, r, d) = map(int, input().split())
	L[l].append([r, d])
	L[r].append([l, -d])
	D[i] = (l, r, d)
C = ['N' for i in range(N + 1)]

def dfs(x):
	for (i, j) in L[x]:
		if C[i] == 'N':
			C[i] = C[x] + j
			dfs(i)
for i in range(1, N + 1):
	if C[i] == 'N':
		C[i] = 0
		dfs(i)
for i in range(M):
	(l, r, d) = D[i]
	if C[r] - C[l] != d:
		print('No')
		exit()
print('Yes')


import sys
(n, m) = map(int, input().split())
ed = [[] for _ in range(n)]
v = [None] * n
for _ in range(m):
	(l, r, d) = map(int, input().split())
	ed[l - 1].append([r - 1, d])
	ed[r - 1].append([l - 1, -d])
visited = [False] * n

def dfs(start):
	global ed, v, visited
	s = [start]
	v[start] = 0
	while s:
		label = s.pop()
		if visited[label] == False:
			visited[label] = True
			for e in ed[label]:
				if v[e[0]] is None:
					v[e[0]] = v[label] + e[1]
					s.append(e[0])
				elif v[e[0]] != v[label] + e[1]:
					print('No')
					sys.exit()
	return
for i in range(n):
	if v[i] is None:
		dfs(i)
print('Yes')


class PotUnionFind:
	__slots__ = ['parent', 'gsize', 'diff_p']

	def __init__(self, n):
		self.parent = list(range(n))
		self.gsize = [1] * n
		self.diff_p = [0] * n

	def root(self, x):
		while self.parent[x] != x:
			self.diff_p[x] += self.diff_p[self.parent[x]]
			self.parent[x] = self.parent[self.parent[x]]
			x = self.parent[x]
		return x

	def weight(self, x):
		c = 0
		while self.parent[x] != x:
			self.diff_p[x] += self.diff_p[self.parent[x]]
			self.parent[x] = self.parent[self.parent[x]]
			c += self.diff_p[x]
			x = self.parent[x]
		return c

	def merge(self, x, y, dxy):
		dxy += self.weight(x) - self.weight(y)
		(x, y) = (self.root(x), self.root(y))
		if x == y:
			return False
		if self.gsize[x] > self.gsize[y]:
			(x, y, dxy) = (y, x, -dxy)
		self.gsize[x] += self.gsize[y]
		self.parent[y] = x
		self.diff_p[y] = dxy
		return True

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

	def diff(self, x, y):
		if self.root(x) == self.root(y):
			return self.weight(y) - self.weight(x)
		else:
			return None

	def size(self, x):
		return self.gsize[self.root(x)]
(n, m) = list(map(int, input().split()))
uf = PotUnionFind(n)
ans = True
for i in range(m):
	(l, r, d) = list(map(int, input().split()))
	l -= 1
	r -= 1
	if uf.issame(l, r):
		ans = d == uf.diff(l, r)
	else:
		uf.merge(l, r, d)
	if ans == False:
		break
if ans == False:
	print('No')
else:
	print('Yes')


import sys
sys.setrecursionlimit(10000)
from collections import defaultdict, deque

def inpl():
	return tuple(map(int, input().split()))
(N, M) = inpl()
Q = [inpl() for _ in range(M)]
tree = [[-1, 1] for _ in range(N + 1)]

def find(i):
	if tree[i][0] == -1:
		group = i
	else:
		group = find(tree[i][0])
		tree[i][0] = group
	return group

def unite(x, y):
	px = find(x)
	py = find(y)
	if tree[px][1] == tree[py][1]:
		tree[py][0] = px
		tree[px][1] += 1
	else:
		if tree[px][1] < tree[py][1]:
			(px, py) = (py, px)
		tree[py][0] = px
adj = [[] for _ in range(N + 1)]
for (l, r, d) in Q:
	if find(l) != find(r):
		unite(l, r)
	adj[l].append([r, d])
	adj[r].append([l, -d])
G = set([find(n) for n in range(1, N + 1)])
X = [-1 for _ in range(N + 1)]
searched = [False for _ in range(N + 1)]
res = True
for g in G:
	X[g] = 0
	Q = deque([g])
	searched[g] = True
	while Q:
		p = Q.popleft()
		for (np, d) in adj[p]:
			if searched[np]:
				if X[np] != X[p] + d:
					Q = []
					res = False
					break
			else:
				X[np] = X[p] + d
				Q.append(np)
				searched[np] = True
	if not res:
		break
if res:
	print('Yes')
else:
	print('No')


import sys
input = sys.stdin.readline

class WeightUnionFind:

	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 dist(self, x):
		self.find(x)
		return self.weight[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
		else:
			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 True

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

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

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

def main():
	(N, M) = map(int, input().split())
	uni = WeightUnionFind(N)
	for _ in range(M):
		(L, R, D) = map(int, input().split())
		L -= 1
		R -= 1
		if uni.same(L, R):
			if D != uni.diff(L, R):
				print('No')
				exit()
		else:
			uni.unite(L, R, D)
	print('Yes')
main()


import sys
INF = 10 ** 9
(N, M) = map(int, input().split())
graph = []
for i in range(N + 1):
	graph.append([])
for i in range(M):
	(L, R, D) = map(int, input().split())
	graph[L].append((R, D))
	graph[R].append((L, -D))
pos_list = [-INF] * (N + 1)
for i in range(1, N + 1):
	if pos_list[i] != -INF:
		continue
	queue = {i}
	pos_list[i] = 0
	while len(queue) > 0:
		new_queue = set()
		for q in queue:
			for (v, d) in graph[q]:
				if pos_list[v] == -INF:
					pos_list[v] = pos_list[q] + d
					new_queue.add(v)
				elif pos_list[v] != pos_list[q] + d:
					print('No')
					sys.exit(0)
		queue = new_queue
print('Yes')


class UF:

	def __init__(self, N):
		self.parents = [-1] * (N + 1)
		self.weight = [0] * (N + 1)

	def union(self, f, t, w):
		w += self.weight[f]
		w -= self.weight[t]
		p1 = self.find(f)
		p2 = self.find(t)
		if p1 == p2:
			return
		if self.parents[p1] > self.parents[p2]:
			(p1, p2) = (p2, p1)
			w = -w
		self.parents[p1] += self.parents[p2]
		self.weight[p2] = w
		self.parents[p2] = p1

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

	def compare_weight(self, x, y):
		self.find(x)
		self.find(y)
		return abs(self.weight[y] - self.weight[x])

	def same(self, n1, n2):
		return self.find(n1) == self.find(n2)
(N, M) = map(int, input().split())
uf = UF(N)
flg = True
for _ in range(M):
	(l, r, d) = map(int, input().split())
	if uf.same(l, r):
		if uf.compare_weight(l, r) != d:
			flg = False
			break
	else:
		uf.union(l, r, d)
print('Yes') if flg else print('No')