CodeEff/ECCO huggingface dataset:
# Original solution
from collections import defaultdict, deque
import sys

readline = sys.stdin.buffer.readline

N, M = list(map(int, readline().split()))
dic = defaultdict(list)
par = [i for i in range(N)]
rank = [0]*N
def find(x):
  if par[x]==x:
    return x
  else:
    par[x] = find(par[x])
    return par[x]
def unit(x, y):
  x = find(x)
  y = find(y)
  if x==y:
    return
  elif rank[x]<rank[y]:
    par[x] = y
    return
  elif rank[y]<rank[x]:
    par[y] = x
  else:
    par[y] = x
    rank[x] += 1

for i in range(M):
  l, r, d = list(map(int, readline().split()))
  dic[l-1] += [(r-1,d)]
  dic[r-1] += [(l-1,-d)]
  unit(l-1, r-1)


dist = [-1]*N
m = []
for x in range(N):
  y = find(x)
  m += [(y,0)]
  dist[y] = 0
m = set(m)
stuck = deque(m)
while stuck:
  e, a = stuck.popleft()
  flag = False
  for c in dic[e]:
    p, d = c
    x = d + dist[e]
    if dist[p]==-1:
      dist[p] = x
      stuck += [(p, x)]
    elif dist[p]!=x:
      print('No')
      flag = True
      break
  if flag:
    break
else:
  print('Yes')

# Optimized solution
from collections import defaultdict, deque
N, M = list(map(int, input().split()))
used = [True]*N
dic = defaultdict(list)
for i in range(M):
  l, r, d = list(map(int,input().split()))
  l -= 1
  r -= 1
  used[r] = False
  dic[l] += [(r,d)]

dist = [-1]*N
q = deque([])
for i in range(N):
  if used[i]:
    q += [i]
    dist[i] = 0

ans = True
while q:
  e = q.popleft()
  flag = False
  for p, d in dic[e]:
    if dist[p]==-1:
      dist[p] = d+dist[e]
      q += [p]
    elif dist[p]!=dist[e]+d:
      ans = False
      flag = True
      break
  if flag:
    break
if ans:
  if -1 not in dist:
    print('Yes')
  else:
    print('No')
else:
  print('No')
# Original solution
def solve(n, query):
    for l, r, d in query:
        if is_same(l, r):
            if d != diff(l, r):
                return 'No'
        else:
            unite(l, r, d)
    return 'Yes'


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


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


def unite(x, y, w):
    w += diff_weight[x]-diff_weight[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
        diff_weight[y] = w
        return True


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


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


if __name__ == '__main__':
    n, m = list(map(int, input().split()))
    par = [-1]*(n+1)
    diff_weight = [0]*(n+1)
    query = []
    for _ in range(m):
        l, r, d = list(map(int, input().split()))
        query.append((l, r, d))
    print((solve(n, query)))


# Optimized solution
def solve(n, query):
    for l, r, d in query:
        if is_same(l, r):
            if d != diff(l, r):
                return 'No'
        else:
            unite(l, r, d)
    return 'Yes'


def unite(x, y, w):
    w += diff_weight[x]-diff_weight[y]
    rt_x = find(x)
    rt_y = find(y)

    if rt_x == rt_y:
        return
    if rank[rt_x] >= rank[rt_y]:
        par[rt_y] = rt_x
        diff_weight[rt_y] = w
        if rank[rt_x] == rank[rt_y]:
            rank[rt_x] += 1
    else:
        par[rt_x] = rt_y
        diff_weight[rt_x] = -w


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


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


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


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


if __name__ == '__main__':
    n, m = list(map(int, input().split()))
    par, rank = [-1]*(n+1), [0]*(n+1)
    diff_weight = [0]*(n+1)
    query = []
    for _ in range(m):
        l, r, d = list(map(int, input().split()))
        query.append((l, r, d))
    print((solve(n, query)))
# Original solution
from collections import deque

N, M = list(map(int, input().split()))
graph = [[] for _ in range(N)]
for _ in range(M):
    l, r, d = list(map(int, input().split()))
    graph[l - 1].append([r - 1, d])
    graph[r - 1].append([l - 1, -d])
X = [None] * N


def bfs(u):
    que = deque([(u, 0)])
    X[u] = 0
    while que:
        u, x = que.popleft()
        for nu, add in graph[u]:
            nx = x + add
            if X[nu] == nx:
                continue
            if X[nu] is not None and X[nu] != nx:
                print('No')
                exit()
            X[nu] = nx
            que.append((nu, nx))


for i in range(N):
    if X[i] is None:
        bfs(i)
print('Yes')


# Optimized solution
from collections import deque

n, m = list(map(int, input().split()))
tree = [[] for _ in range(n)]
for _ in range(m):
    L, R, D = list(map(int, input().split()))
    tree[L - 1].append((R - 1, D))
    tree[R - 1].append((L - 1, -D))
visited = [None for _ in range(n)]


def bfs(u):
    q = deque([[u, 0]])
    visited[u] = 0
    while q:
        u, dist = q.popleft()
        for next_u, d in tree[u]:
            next_x = dist + d
            if visited[next_u] is None:
                visited[next_u] = next_x
                q.append([next_u, next_x])
            elif visited[next_u] == next_x:
                continue
            else:
                print("No")
                exit()


for i in range(n):
    if visited[i] is None:
        bfs(i)
else:
    print('Yes')
# Original solution
import sys
input=sys.stdin.readline

from collections import deque
N,M=list(map(int,input().split()))
if M==0:
    print("Yes")
    quit()
G=[[] for i in range(N)]
for i in range(M):
    l,r,d=list(map(int,input().split()))
    G[l-1].append((l-1,r-1,d))
    G[r-1].append((r-1,l-1,-d))
x=["a"]*N
y=[1]*N
z=[[0]*N for i in range(N)]
stack=deque()
for i in range(N):
    if y[i]:
        stack.extend(G[i])
        y[i]=0
    if len(stack)==0:
        continue
    while(stack):
        l,r,d=stack.popleft()
        if x[l]=="a":
            x[l]=0
        if x[r]=="a":
            x[r]=x[l]+d
            continue
        if x[r]!=x[l]+d:
            print("No")
            quit()
        y[r]=0
        z[l][r]=1
        for l1,r1,d1 in G[r]:
            if z[l1][r1]:
                continue
            stack.append((l1,r1,d1))
if max(x)-min(x)>10**9:
    print("No")
else:
    print("Yes")


# Optimized solution
from collections import deque
N,M=list(map(int,input().split()))
if M==0:
    print("Yes")
    quit()
G=[[] for i in range(N)]
for i in range(M):
    l,r,d=list(map(int,input().split()))
    G[l-1].append((l-1,r-1,d))
    G[r-1].append((r-1,l-1,-d))
x=["a"]*N
y=[1]*N
z=[[0]*N for i in range(N)]
stack=deque()
for i in range(N):
    if y[i]:
        stack.extend(G[i])
        y[i]=0
    if len(stack)==0:
        continue
    while(stack):
        l,r,d=stack.popleft()
        if x[l]=="a":
            x[l]=0
        if x[r]=="a":
            x[r]=x[l]+d
            continue
        if x[r]!=x[l]+d:
            print("No")
            quit()
        y[r]=0
        z[l][r]=1
        z[r][l]=1
        for l1,r1,d1 in G[r]:
            if z[l1][r1] or z[r1][l1]:
                continue
            stack.append((l1,r1,d1))
if max(x)-min(x)>10**9:
    print("No")
else:
    print("Yes")
# Original solution
from collections import deque
N,M=list(map(int,input().split()))
if M==0:
    print("Yes")
    quit()
G=[[] for i in range(N)]
for i in range(M):
    l,r,d=list(map(int,input().split()))
    G[l-1].append((l-1,r-1,d))
    G[r-1].append((r-1,l-1,-d))
x=["a"]*N
y=[1]*N
z=[[0]*N for i in range(N)]
stack=deque()
for i in range(N):
    if y[i]:
        stack.extend(G[i])
        y[i]=0
    if len(stack)==0:
        continue
    while(stack):
        l,r,d=stack.popleft()
        if x[l]=="a":
            x[l]=0
        if x[r]=="a":
            x[r]=x[l]+d
            continue
        if x[r]!=x[l]+d:
            print("No")
            quit()
        y[r]=0
        z[l][r]=1
        z[r][l]=1
        for l1,r1,d1 in G[r]:
            if z[l1][r1] or z[r1][l1]:
                continue
            stack.append((l1,r1,d1))
if max(x)-min(x)>10**9:
    print("No")
else:
    print("Yes")


# Optimized solution
#重み付きUnion-Find

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

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


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

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

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

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

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

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

for i in range(m):
    l,r,d = list(map(int,input().split()))
    l,r = l-1,r-1
    if same(l,r):
        if d != diff(l,r):
            print('No')
            exit()
    else:
        unite(l,r,d)
print('Yes')
# Original solution
from collections import deque
inf = 10 ** 10

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

graph = [[] for i in range(N)]
dis = [[inf]*N for i in range(N)]

for i in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1
    R -= 1
    graph[L].append(R)
    graph[R].append(L)
    dis[L][R] = D
    dis[R][L] = (-1)*D

data = [inf]*N
det = 0

for i in range(N):
    if data[i] != inf:
        continue
    data[i] = 0
    stack = deque()
    stack.append(i)
    while stack:
        x = stack.pop()
        for y in graph[x]:
            if data[y] == inf:
                data[y] = data[x] + dis[x][y]
                stack.append(y)
            else:
                if data[y] - data[x] != dis[x][y]:
                    det = -1
                    break
    if det == -1:
        break

if det == 0:
    print("Yes")
else:
    print("No")



# Optimized solution
from collections import deque
inf = 10 ** 10

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

graph = [[] for i in range(N)]
dis = [[inf]*N for i in range(N)]

for i in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1
    R -= 1
    graph[L].append(R)
    graph[R].append(L)
    dis[L][R] = D
    dis[R][L] = (-1)*D

data = [inf]*N
det = 0

for i in range(N):
    if data[i] != inf:
        continue
    data[i] = 0
    stack = deque()
    stack.append(i)
    while stack:
        x = stack.popleft()
        for y in graph[x]:
            if data[y] == inf:
                data[y] = data[x] + dis[x][y]
                stack.append(y)
            else:
                if data[y] - data[x] != dis[x][y]:
                    det = -1
                    break
    if det == -1:
        break

if det == 0:
    print("Yes")
else:
    print("No")
# Original solution
from collections import deque
inf = 10 ** 10

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

graph = [[] for i in range(N)]
dis = [[inf]*N for i in range(N)]

for i in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1
    R -= 1
    graph[L].append(R)
    graph[R].append(L)
    dis[L][R] = D
    dis[R][L] = (-1)*D

data = [inf]*N
det = 0

for i in range(N):
    if data[i] != inf:
        continue
    data[i] = 0
    stack = deque()
    stack.append(i)
    while stack:
        x = stack.popleft()
        for y in graph[x]:
            if data[y] == inf:
                data[y] = data[x] + dis[x][y]
                stack.append(y)
            else:
                if data[y] - data[x] != dis[x][y]:
                    det = -1
                    break
    if det == -1:
        break

if det == 0:
    print("Yes")
else:
    print("No")



# Optimized solution
from collections import deque

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

graph = [[] for i in range(N)]
dis = [["n/a"]*N for i in range(N)]

for i in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1
    R -= 1
    graph[L].append(R)
    graph[R].append(L)
    dis[L][R] = D
    dis[R][L] = (-1)*D

data = ["n/a"]*N
det = 0

for i in range(N):
    if data[i] != "n/a":
        continue
    data[i] = 0
    stack = deque()
    stack.append(i)
    while stack:
        x = stack.popleft()
        for y in graph[x]:
            if data[y] == "n/a":
                data[y] = data[x] + dis[x][y]
                stack.append(y)
            else:
                if data[y] - data[x] != dis[x][y]:
                    det = -1
                    break
    if det == -1:
        break

if det == 0:
    print("Yes")
else:
    print("No")
# Original solution
from collections import deque
import sys
input = sys.stdin.readline

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

graph = [[] for i in range(N)]
dis = [[None]*N for i in range(N)]

for i in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1
    R -= 1
    graph[L].append(R)
    graph[R].append(L)
    dis[L][R] = D
    dis[R][L] = (-1)*D

data = [None]*N

for i in range(N):
    if data[i] != None:
        continue
    data[i] = 0
    stack = deque()
    stack.append(i)
    while stack:
        x = stack.popleft()
        for y in graph[x]:
            if data[y] == None:
                data[y] = data[x] + dis[x][y]
                stack.append(y)
            else:
                if data[y] - data[x] != dis[x][y]:
                    print("No")
                    sys.exit()
    
print("Yes")



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

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

graph = [[] for i in range(N)]

for i in range(M):
    L,R,D = list(map(int,input().split()))
    L -= 1
    R -= 1
    graph[L].append([R,D])
    graph[R].append([L,-D])
    
data = [None]*N

for i in range(N):
    if data[i] != None:
        continue
    data[i] = 0
    stack = deque()
    stack.append(i)
    while stack:
        x = stack.popleft()
        for y in graph[x]:
            if data[y[0]] == None:
                data[y[0]] = data[x] + y[1]
                stack.append(y[0])
            else:
                if data[y[0]] - data[x] != y[1]:
                    print("No")
                    sys.exit()
    
print("Yes")
# Original solution
# -*- coding: utf-8 -*-
### 幅優先探索により矛盾を探す
import sys
from collections import deque
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

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

dist = [0]*N
done = [0]*N  
def bfs(i):
    q = deque([i])
    while q:
        x = q.popleft()
        for y,d in graph[x]:
            if done[y] == 0:
                done[y] = 1
                dist[y] = dist[x]+ d
                q.append(y)
            else:
                if dist[y] != dist[x]+d:
                    return 0
    return 1

for i in range(N):
    if done[i] == 0:
        done[i] = 1
        if bfs(i) == 0:
            print('No')
            sys.exit()
print('Yes')

# Optimized solution
# -*- coding: utf-8 -*-
#重み付きUnion-Findによる実装
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

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

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


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

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

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

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

N,M = list(map(int,readline().split()))
#0-index
par = [-1]*N
wei = [0]*N
for _ in range(M):
    l,r,d = list(map(int,readline().split()))
    l,r = l-1,r-1
    if same(l,r):
        if d != diff(l,r):
            print('No')
            exit()
    else:
        unite(l,r,d)
print('Yes')
# Original solution
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


from collections import defaultdict
n,m = list(map(int, input().split()))
ns = defaultdict(set)
for _ in range(m):
    u,v,c = list(map(int, input().split()))
    u -= 1
    v -= 1
    ns[u].add((c,v))
    ns[v].add((-c,u))
vals = [None] * n
def dijkstra(start):
    import heapq
    h = [(0, start)] # (距離, ノード番号)
    vals[start] = 0
    ans = True
    while h:
        val, u = heapq.heappop(h)
        for d, v in ns[u]:
            if vals[v] is None:
                vals[v] = val+d
                heapq.heappush(h, (vals[v], v))
            else:
                if vals[v]!=val+d:
                    return False
    return ans

for start in range(n):
    if vals[start] is not None:
        continue
    res = dijkstra(start)
    if not res:
        print("No")
        break
else:
    print("Yes")

# Optimized solution
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


from collections import defaultdict
n,m = list(map(int, input().split()))
ns = defaultdict(set)
for _ in range(m):
    u,v,c = list(map(int, input().split()))
    u -= 1
    v -= 1
    ns[u].add((c,v))
    ns[v].add((-c,u))
vals = [None] * n
def dijkstra(start):
    h = [start]
    vals[start] = 0
    ans = True
    while h:
        u = h.pop()
        for d, v in ns[u]:
            if vals[v] is None:
                vals[v] = vals[u]+d
                h.append(v)
            else:
                if vals[v]!=vals[u]+d:
                    return False
    return ans

for start in range(n):
    if vals[start] is not None:
        continue
    res = dijkstra(start)
    if not res:
        print("No")
        break
else:
    print("Yes")
# Original solution
def main():
    from collections import deque
    import sys
    input = sys.stdin.readline

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

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

    dist = [-1] * N

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

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

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

    print('Yes')


if __name__ == '__main__':
    main()


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

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

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

    dist = [-1] * N

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

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

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

    print('Yes')


if __name__ == '__main__':
    main()
# Original solution
class UnionFindTree:
    def __init__(self, size):
        self.table = [-1 for _ in range(size)]
    
    def find_root(self, x):
        while 0 <= self.table[x]:
            x = self.table[x]
        return x

    def union(self, x, y):
        r1 = self.find_root(x)
        r2 = self.find_root(y)
        if r1 != r2:
            self.table[r2] = r1
    
    def __repr__(self):
        return repr(self.table)

def check(root, group, l, r, d):
    seen = set()
    table = {}
    table[root] = 0
    seen.add(root)
    while len(seen) != len(group):
        for li, ri, di in zip(l, r, d):
            if (li not in seen) and (ri not in seen):
                continue
            if (li in seen) and (ri in seen):
                if table[li]+di != table[ri]:
                    return False
            elif li in seen:
                table[ri] = table[li] + di
                seen.add(ri)
            elif ri in seen:
                table[li] = table[ri] - di
                seen.add(li)
    return True

def main():
    n, m = list(map(int, input().split()))
    l, r, d = [], [], []
    seen = set()
    tree = UnionFindTree(n+1)
    for i in range(m):
        li, ri, di = list(map(int, input().split()))
        l.append(li)
        r.append(ri)
        d.append(di)
        seen.add(li)
        seen.add(ri)
        tree.union(li, ri)
    
    groups = {}
    for s in seen:
        root = tree.find_root(s)
        if root not in groups:
            groups[root] = set()
        groups[root].add(s)
    
    for root in groups:
        if not check(root, groups[root], l, r, d):
            print('No')
            return
    print('Yes')

main()


# Optimized solution
class UnionFindTree:
    def __init__(self, size):
        self.parent = list(range(size))
        self.dist = [0] * size

    def find_root(self, x):
        if self.parent[x] == x:
            return x, 0
        else:
            self.parent[x], d = self.find_root(self.parent[x])
            self.dist[x] += d
            return self.parent[x], self.dist[x]

    def union(self, x, y, d):
        r1, d1 = self.find_root(x)
        r2, d2 = self.find_root(y)
        if r1 != r2:
            self.parent[r2] = r1
            self.dist[r2] = (d1 - d2) + d
        else:
            if (d2 - d1) != d:
                return False
        return True

def main():
    n, m = list(map(int, input().split()))
    tree = UnionFindTree(n+1)
    for i in range(m):
        l, r, d = list(map(int, input().split()))
        if not tree.union(l, r, d):
            print('No')
            return
    print('Yes')

main()