Problem:
 Score : 400 points    Problem Statement There are N people standing on the x -axis.
Let the coordinate of Person i be x_i .
For every i , x_i is an integer between 0 and 10^9 (inclusive).
It is possible that more than one person is standing at the same coordinate.  You will given M pieces of information regarding the positions of these people.
The i -th piece of information has the form (L_i, R_i, D_i) .
This means that Person R_i is to the right of Person L_i by D_i units of distance, that is, x_{R_i} - x_{L_i} = D_i holds.  It turns out that some of these M pieces of information may be incorrect.
Determine if there exists a set of values (x_1, x_2, ..., x_N) that is consistent with the given pieces of information.      Constraints  1 \leq N \leq 100  000  0 \leq M \leq 200  000  1 \leq L_i, R_i \leq N ( 1 \leq i \leq M )  0 \leq D_i \leq 10  000 ( 1 \leq i \leq M )  L_i \neq R_i ( 1 \leq i \leq M )  If i \neq j , then (L_i, R_i) \neq (L_j, R_j) and (L_i, R_i) \neq (R_j, L_j) .  D_i are integers.         Input Input is given from Standard Input in the following format:  N  M  L_1  R_1  D_1  L_2  R_2  D_2  :  L_M  R_M  D_M       Output If there exists a set of values (x_1, x_2, ..., x_N) that is consistent with all given pieces of information, print Yes ; if it does not exist, print No .        Sample Input 1 3 3
1 2 1
2 3 1
1 3 2      Sample Output 1 Yes  Some possible sets of values (x_1, x_2, x_3) are (0, 1, 2) and (101, 102, 103) .       Sample Input 2 3 3
1 2 1
2 3 1
1 3 5      Sample Output 2 No  If the first two pieces of information are correct, x_3 - x_1 = 2 holds, which is contradictory to the last piece of information.       Sample Input 3 4 3
2 1 1
2 3 5
3 4 2      Sample Output 3 Yes       Sample Input 4 10 3
8 7 100
7 9 100
9 8 100      Sample Output 4 No       Sample Input 5 100 0      Sample Output 5 Yes

Solution (Python):
import sys

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

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

    
    def Unite(self, x, y, d):
        d+=self.potential[x]-self.potential[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
            self.potential[y]=d

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            self.potential[x]=-d
            
            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)]
    
    def dist(self,x,y):
        if self.isSameGroup(x,y):
            return self.potential[y]-self.potential[x]
        else: return -10**10



INF=10**10

N,M=map(int,input().split())
if M==0: print("Yes"),sys.exit()

tree=UnionFind(N)
dist=[list(map(int,input().split())) for i in range(M)]

for i in range(M):
    l,r,d=dist[i]
    if tree.isSameGroup(l,r) and tree.dist(l,r)!=d: print("No"),sys.exit()
    tree.Unite(l,r,d)

print("Yes")

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
N, M =map(int, input().split())
G=[[]for i in range(N+1)]
for i in range(M):
    a, b, c = map(int,input().split())
    G[a] += (b,c),
    G[b] += (a,-c),

d = [10**9]*(N+1)
flag = True
def f(v, u):
    global flag
    if not flag:
        d[v] = 0
        return 0
    else:
        d[v] = u
        for t, c in G[v] :
            if d[t] == 10**9:
                f(t, u+c)
            else:
                if d[t] != u+c:
                    flag = False
                    
for i in range(1, N+1):
    if d[i] == 10**9:
        f(i, 0)
if flag:
    print('Yes')
else:
    print('No')

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
n, m = map(int, input().split())

INF = float("inf")

cost = [INF] * (n+1)

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


def solve(i, c):
  
  if cost[i] == INF:
    cost[i] = c
    
    for j, d in edges[i]:
      if solve(j, c + d) == False:
        return False
  
  return cost[i] == c

ans = "Yes"

for i in range(1, n+1):
  if cost[i] == INF and solve(i, 0) == False:
    ans = "No"
    
    
print(ans)

Solution (Python):
N, M = map(int, input().split())

LIMIT = 10 ** 9

class UnionFind():
    def __init__(self, N):
        self.nodes = [i for i in range(N)]
        self.distance = [0 for _ in range(N)]

    def root(self, x):
        if x != self.nodes[x]:
            root, distance = self.root(self.nodes[x])
            if self.nodes[x] != root:
                self.distance[x] += distance
                self.nodes[x] = root
        return self.nodes[x], self.distance[x]

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

    
    def unite(self, x, y, distance):
        if self.same(x, y):
            return self.distance[y] - self.distance[x] == distance
        x_root, _ = self.root(x)
        y_root, _ = self.root(y)
        self.distance[y_root] = self.distance[x] + distance - self.distance[y]
        self.nodes[y_root] = x_root
        return True

is_correct = True
uf = UnionFind(N)
for _ in range(M):
    l, r, d = map(int, input().split())
    is_valid = uf.unite(l-1, r-1, d)
    if not is_valid:
        is_correct = False
        break

distance_dict = {}
for group, distance in zip(uf.nodes, uf.distance):
    if group in distance_dict:
        distance_dict[group]["max"] = max(distance_dict[group]["max"], distance)
        distance_dict[group]["min"] = min(distance_dict[group]["min"], distance)
    else:
        distance_dict[group] = {
            "max": distance,
            "min": distance,
        }

for distances in distance_dict.values():
    if distances["max"] - distances["min"] > LIMIT:
        is_correct = False
        break
print("Yes" if is_correct else "No")

Solution (Python):
import sys
input = sys.stdin.readline
n,m=map(int,input().split())
par = [-1]*n
wei = [0]*n

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

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


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

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

def size(x):
    return -par[find(x)]

def diff(x,y):
    return weight(y)-weight(x)
flag=1
for i in range(m):
  l,r,d=map(int,input().split())
  if same(l-1,r-1):
    if d!=diff(l-1,r-1):
      flag=0
  else:
    unite(l-1,r-1,d)
print("No" if flag==0 else "Yes")

Solution (Python):
import sys
input = sys.stdin.readline




N,M = map(int,input().split())
root = list(range(N+1))
pos = [0] * (N+1) 
depth = [0] * (N+1)

def find_root(x):
  
  y = root[x]
  if x == y:
    return y,0
  z,p = find_root(y)
  root[x] = z
  pos[x] += p
  return z,pos[x]

def merge(x,y,d):
  
  rx,px = find_root(x)
  ry,py = find_root(y)
  if rx == ry:
    return (py == px + d)
  
  
  dd = px-py+d
  if depth[rx] > depth[ry]:
    root[ry] = rx
    pos[ry] = dd
  else:
    root[rx] = ry
    pos[rx] = -dd
    depth[ry] += 1
  return True

answer = 'Yes'
for _ in range(M):
  L,R,D = map(int,input().split())
  if not merge(L,R,D):
    answer = 'No'
    break
print(answer)

Solution (Python):
import sys
input = sys.stdin.readline
inf = float('inf')
mod = 10**9+7


def INT_(n): return int(n)-1


def MI(): return map(int, input().split())


def MF(): return map(float, input().split())


def MI_(): return map(INT_, input().split())


def LI(): return list(MI())


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


def LF(): return list(MF())


def LIN(n: int): return [input() for _ in range(n)]


def LLIN(n: int): return [LI() for _ in range(n)]


def LLIN_(n: int): return [LI_() for _ in range(n)]


def LLI(): return [list(map(int, l.split())) for l in input()]


def I(): return int(input())


def F(): return float(input())


def ST(): return input().replace('\n', '')


def main():

    class WeightedUnionFind():
        def __init__(self, n):
            self.nodes = [-1 for _ in range(n)]
            self.weight = [0] * n

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

        def unite(self, x, y, w):
            w += self.weight[x]-self.weight[y]
            root_x = self.get_root(x)
            root_y = self.get_root(y)
            if root_x != root_y:
                
                if self.nodes[root_x] > self.nodes[root_y]:
                    root_x, root_y = root_y, root_x
                    w *= -1
                self.nodes[root_x] += self.nodes[root_y]
                self.nodes[root_y] = root_x
                self.weight[root_y] = w

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

        def same(self, x, y):
            return get_root(x) == get_root(y)
    N, M = MI()
    uf = WeightedUnionFind(N)
    get_root, unite, nodes, diff, same = uf.get_root, uf.unite, uf.nodes, uf.diff, uf.same
    for _ in range(M):
        l, r, d = MI_()
        d += 1
        if same(l, r) and diff(l, r) != d:
            print("No")
            exit()
        else:
            unite(l, r, d)
    print("Yes")


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.readline
inf = float('inf')
mod = 10**9+7


def INT_(n): return int(n)-1


def MI(): return map(int, input().split())


def MF(): return map(float, input().split())


def MI_(): return map(INT_, input().split())


def LI(): return list(MI())


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


def LF(): return list(MF())


def LIN(n: int): return [input() for _ in range(n)]


def LLIN(n: int): return [LI() for _ in range(n)]


def LLIN_(n: int): return [LI_() for _ in range(n)]


def LLI(): return [list(map(int, l.split())) for l in input()]


def I(): return int(input())


def F(): return float(input())


def ST(): return input().replace('\n', '')


def main():

    class WeightedUnionFind():
        def __init__(self, n):
            self.nodes = [-1 for _ in range(n)]
            self.weight = [0] * n

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

        def unite(self, x, y, w):
            w += self.weight[x]-self.weight[y]
            root_x = self.get_root(x)
            root_y = self.get_root(y)
            if root_x != root_y:
                
                if self.nodes[root_x] > self.nodes[root_y]:
                    root_x, root_y = root_y, root_x
                    w *= -1
                self.nodes[root_x] += self.nodes[root_y]
                self.nodes[root_y] = root_x
                self.weight[root_y] = w

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

        def same(self, x, y):
            return get_root(x) == get_root(y)
    N, M = MI()
    edge = [[] for _ in range(N)]
    uf = WeightedUnionFind(N)
    get_root, unite, nodes, diff, same = uf.get_root, uf.unite, uf.nodes, uf.diff, uf.same
    distanse = [0] * N
    distanse[0] = 0
    rev_edge = [[]for _ in range(N)]
    for _ in range(M):
        l, r, d = MI_()
        d += 1
        edge[l].append((r, d))
        if same(l, r) and diff(l, r) != d:
            print("No")
            exit()
        else:
            unite(l, r, d)

    print("Yes")


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.readline
inf = float('inf')
mod = 10**9+7


def INT_(n): return int(n)-1


def MI(): return map(int, input().split())


def MF(): return map(float, input().split())


def MI_(): return map(INT_, input().split())


def LI(): return list(MI())


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


def LF(): return list(MF())


def LIN(n: int): return [input() for _ in range(n)]


def LLIN(n: int): return [LI() for _ in range(n)]


def LLIN_(n: int): return [LI_() for _ in range(n)]


def LLI(): return [list(map(int, l.split())) for l in input()]


def I(): return int(input())


def F(): return float(input())


def ST(): return input().replace('\n', '')


def main():

    class WeightedUnionFind():
        def __init__(self, n):
            self.nodes = [-1 for _ in range(n)]
            self.weight = [0] * n

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

        def unite(self, x, y, w):
            w += self.weight[x]-self.weight[y]
            root_x = self.get_root(x)
            root_y = self.get_root(y)
            if root_x != root_y:
                
                if self.nodes[root_x] > self.nodes[root_y]:
                    root_x, root_y = root_y, root_x
                    w *= -1
                self.nodes[root_x] += self.nodes[root_y]
                self.nodes[root_y] = root_x
                self.weight[root_y] = w

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

        def same(self, x, y):
            return get_root(x) == get_root(y)
    N, M = MI()
    edge = [[] for _ in range(N)]
    uf = WeightedUnionFind(N)
    get_root, unite, nodes, diff, same = uf.get_root, uf.unite, uf.nodes, uf.diff, uf.same
    distanse = [0] * N
    distanse[0] = 0
    rev_edge = [[]for _ in range(N)]
    for _ in range(M):
        l, r, d = MI_()
        d += 1
        edge[l].append((r, d))
        if same(l, r) and diff(l, r) != d:
            print("No")
            exit()
        else:
            unite(l, r, d)

    print("Yes")


if __name__ == '__main__':
    main()

Solution (Python):
import sys
input = sys.stdin.readline
n, m = map(int, input().split())

parent = [i for i in range(n + 1)]
rank = [0] * (n + 1)
weight = [0] * (n + 1)

def find(x):
    if parent[x] == x:
        return x
    else:
        y = find(parent[x])
        weight[x] += weight[parent[x]]
        parent[x] = y
        return y

def union(x, y, w):
    rx = find(x)
    ry = find(y)
    if rank[rx] < rank[ry]:
        parent[rx] = ry
        weight[rx] = w - weight[x] + weight[y]
    else:
        parent[ry] = rx
        weight[ry] = -w - weight[y] + weight[x]
        if rank[rx] == rank[ry]:
            rank[rx] += 1

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

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

ans = "Yes"
for i in range(m):
    l, r, d = map(int, input().split())
    if same_check(l, r):
        if diff(l, r) != d:
            ans = "No"
            break
    else:
        union(l, r, d)
print(ans)

Solution (Python):
N,M=map(int,input().split())
checked=set()
from collections import defaultdict
branch=defaultdict(dict)
flag=True
for i in range(M):
    L,R,D=map(int,input().split())
    branch[L-1][R-1]=D
    branch[R-1][L-1]=-1*D
for i in range(N):
    if i in checked:
        continue
    if not flag:
        break
    dist=dict()
    dist[i]=0
    check={i}
    while len(check)>0:
        now=check.pop()
        checked|={now}
        for nex,d in branch[now].items():
            if nex not in dist.keys():
                dist[nex]=dist[now]+d
                check|={nex}
            elif dist[nex]!=dist[now]+d:
                flag=False
                check=set()
                break
if flag:
    print('Yes')
else:
    print('No')

Solution (Python):
def main():
    import sys
    input = sys.stdin.readline
    

    
    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 i in range(m):
        l,r,d = 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')
            
if __name__ == '__main__':
    main()

Solution (Python):



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 i in range(m):
    l,r,d = 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')

Solution (Python):
n,m = map(int,input().split())
c = list(range(n+1)) 
a = [] 
for i in range(n+1):
  a.append([i])
b = [1]*(n+1) 
p = [0]*(n+1) 

for i in range(m):
  x,y,d = map(int,input().split())
  u = c[x]
  v = c[y]
  if b[u] < b[v]:
    x,y = y,x
    u,v = v,u
    d = -d
  if u != v:
    l = d + p[x] - p[y]
    for t in a[v]:
      c[t] = u
      p[t] += l
    a[u] += a[v]
    a[v] = []
    b[u] += b[v]
    b[v] = 0
  else:
    if not p[y]-p[x] == d:
      
      print("No")
      quit()
print("Yes")

Solution (Python):
N,M = [ int(it) for it in input().split() ]
li = [ [ int(it) for it in input().split() ] for i in range(M) ]

up = [ set([]) for i in range(N)]
dw = [ set([]) for i in range(N)]

for l,r,d in li:
  dw[l-1].add(r-1)
  up[r-1].add(l-1)

S = []
for n in range(N):
  if ( len(up[n])==0 ):
    S.append(n)
L = []
for i in range(N+M):

  if ( len(S)==0 ):
    break
  n = S.pop()
  L.append(n)
  for r in dw[n]:
    up[r].discard(n)
    if ( len(up[r]) == 0 ):
      S.append(r)
  dw[n]=set()

BREAK=False
if (sum([len(s) for s in up])>0):
    BREAK=True

dwl = [ set([]) for i in range(N)]
for l,r,d in li:
  dwl[l-1].add((r-1,d))

dis = [-1]*N

for n in L:
  if (BREAK):
    break
  if (dis[n]==-1):
    dis[n]=0
  for r,d in dwl[n]:
    if (dis[r]==-1):
        dis[r]=dis[n]+d
    else:
        if not (dis[r]==dis[n]+d):
            BREAK=True
            break
if (BREAK):
    print ("No")
else:
    print ("Yes")

Solution (Python):

from collections import defaultdict
from Queue import Queue
import sys
N,M=map(int,sys.stdin.readline().split())
L=[None]*200001
R=[None]*200001
D=[None]*200001
C=defaultdict(list)
done=[False]*200001
if M==0:
    print("Yes")
    sys.exit(0)

class UnionFind(object):
    
    def __init__(self, n=1):
        self.par = [i for i in range(n)]
        self.rank = [0 for _ in range(n)]
        self.size = [1 for _ in range(n)]

    def find(self, x):
        """
        x が属するグループを探索
        """
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def union(self, x, y):
        """
        x と y のグループを結合
        """
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.par[y] = x
            self.size[x] += self.size[y]

    def is_same(self, x, y):
        """
        x と y が同じグループか否か
        """
        return self.find(x) == self.find(y)

    def get_size(self, x):
        """
        x が属するグループの要素数
        """
        x = self.find(x)
        return self.size[x]

uf=UnionFind(n=N+1)
for i in xrange(M):
    l,r,d=map(int,sys.stdin.readline().split())
    L[i]=l
    R[i]=r
    D[i]=d
    C[l].append(i);C[r].append(i)
    uf.union(l,r)
groups={}
for i in range(1,N+1):
    groups[uf.find(i)]=i

X=[None]*200001
for group in groups:
    Q=Queue()
    X[group]=0
    for c in C[group]:
        Q.put(c)
        done[c]=True
    while not Q.empty():
        q=Q.get()
        
        l=L[q];r=R[q];d=D[q]
        ll=rr=False
        if X[l]!=None:
            if X[r] is None:
                rr=True
                X[r]=X[l]+d
            else:
                if X[r]!=X[l]+d: 
                    print("No")
                    sys.exit(0)
        elif X[r]!=None:
            if X[l] is None:
                ll=True
                X[l]=X[r]-d
            else:
                if X[r]!=X[l]+d:
                    print("No")
                    sys.exit(0)
        else:
            sys.exit(1)
        if ll:            
            for c in C[l]:
                if not done[c]:
                    Q.put(c); done[c]=True
        if rr:
            for c in C[r]:
                if not done[c]:
                    Q.put(c); done[c]=True
        




print("Yes")

Solution (Python):
from collections import defaultdict

N,M = map(int,input().split(" "))
G = defaultdict(lambda:[])
D = defaultdict(lambda:-1)
E = defaultdict(lambda:0)
for i in range(M):
    l,r,d = map(int,input().split(" "))
    l -= 1
    r -= 1
    G[l].append((r,d))
    E[r] = 1
for i in range(N):
    if E[i]:
        continue
        
    s = [i]
    
    while len(s):
        l = s.pop()
        for r,d in G[l]:
            if D[r] != -1:
                continue
                
            D[r] = D[l] + d
            s.append(r)
for l in range(N):
    for r,d in G[l]:
        if D[l] + d == D[r]:
            continue
        print("No")
        exit()

print("Yes")

Solution (Python):
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):
        if self.same(x, y):
            return self.weight[x] - self.weight[y]
n, m=map(int, input().split())
U=WeightedUnionFind(n)
def C(U):
    for i in range(m):
        l, r, d = map(int, input().split())
        if U.same(l-1, r-1):
            if U.diff(l-1, r-1)!=d:
                return False
        else:
            U.union(l-1, r-1, d)
    return True
if C(U):
    print('Yes')
else:
    print('No')

Solution (Python):
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())
U=WeightedUnionFind(n)
def C(U):
    for i in range(m):
        l, r, d = map(int, input().split())
        if U.same(l-1, r-1):
            if U.diff(l-1, r-1)!=d:
                return False
        else:
            U.union(l-1, r-1, d)
    return True
if C(U):
    print('Yes')
else:
    print('No')

Solution (Python):

def IL(): return list(map(int,input().split()))
def SL(): return input().split()
def I(): return int(input())
def S(): return list(input())

class WeightedUnionFind:
    def __init__(self, size):
        """
        :param collections.Iterable nodes:
        """
        self._parents = [i for i in range(size)]
        self._ranks = [0 for _ in range(size)]
        self._sizes = [1 for _ in range(size)]
        
        self._weights = [0 for _ in range(size)]
 
    def unite(self, x, y, w):
        """
        x が属する木と y が属する木を併合
        :param x:
        :param y:
        :param w: x と y の重みの差; (重み y) - (重み x)
        :return:
        """
        rx = self.find(x)
        ry = self.find(y)
        if rx == ry:
            return
 
        
        if self._ranks[rx] > self._ranks[ry]:
            
            self._parents[ry] = rx
            self._sizes[rx] += self._sizes[ry]
            
            self._weights[ry] = w + self._weights[x] - self._weights[y]
        else:
            
            self._parents[rx] = ry
            self._sizes[ry] += self._sizes[rx]
            
            self._weights[rx] = -w + self._weights[y] - self._weights[x]
            if self._ranks[rx] == self._ranks[ry]:
                self._ranks[ry] += 1
 
    def find(self, x):
        """
        x が属する木の root
        :param x:
        :return:
        """
        if self._parents[x] == x:
            return x
        root = self.find(self._parents[x])
        self._weights[x] += self._weights[self._parents[x]]
        self._parents[x] = root
        return root
 
    def size(self, x):
        """
        x が属する木のノード数
        :param x:
        :return:
        """
        return self._sizes[self.find(x)]
 
    def weight(self, x):
        """
        :param x:
        :return:
        """
        
        self.find(x)
        return self._weights[x]
 
    def diff(self, x, y):
        """
        (y の重み) - (x の重み)
        :param x:
        :param y:
        :return:
        """
        if self.find(x) == self.find(y):
            return self._weights[y] - self._weights[x]
        return float('inf')
    
    def is_same(self,x,y):
        if self.find(x) == self.find(y):
            return True
        else:
            return False
        
n,m=IL()
UF=WeightedUnionFind(n)
for i in range(m):
    l,r,d=IL()
    if UF.is_same(l-1,r-1) and UF.diff(l-1,r-1)!=d:
        print("No")
        break
    UF.unite(l-1,r-1,d)
else:
    print("Yes")

Solution (Python):
import sys

sys.setrecursionlimit(10000)
INF = float('inf')


class WeightedUnionFind:
    def __init__(self, size):
        """
        :param collections.Iterable nodes:
        """
        self._parents = [i for i in range(size)]
        self._ranks = [0 for _ in range(size)]
        self._sizes = [1 for _ in range(size)]
        
        self._weights = [0 for _ in range(size)]

    def unite(self, x, y, w):
        """
        x が属する木と y が属する木を併合
        :param x:
        :param y:
        :param w: x と y の重みの差; (重み y) - (重み x)
        :return:
        """
        rx = self.find(x)
        ry = self.find(y)
        if rx == ry:
            return

        
        if self._ranks[rx] > self._ranks[ry]:
            
            self._parents[ry] = rx
            self._sizes[rx] += self._sizes[ry]
            
            self._weights[ry] = w + self._weights[x] - self._weights[y]
        else:
            
            self._parents[rx] = ry
            self._sizes[ry] += self._sizes[rx]
            
            self._weights[rx] = -w + self._weights[y] - self._weights[x]
            if self._ranks[rx] == self._ranks[ry]:
                self._ranks[ry] += 1

    def find(self, x):
        """
        x が属する木の root
        :param x:
        :return:
        """
        if self._parents[x] == x:
            return x
        root = self.find(self._parents[x])
        self._weights[x] += self._weights[self._parents[x]]
        self._parents[x] = root
        return root

    def size(self, x):
        """
        x が属する木のノード数
        :param x:
        :return:
        """
        return self._sizes[self.find(x)]

    def weight(self, x):
        """
        :param x:
        :return:
        """
        
        self.find(x)
        return self._weights[x]

    def diff(self, x, y):
        """
        (y の重み) - (x の重み)
        :param x:
        :param y:
        :return:
        """
        if self.find(x) == self.find(y):
            return self._weights[y] - self._weights[x]
        return float('inf')


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

uf = WeightedUnionFind(N + 1)

ok = True
for _ in range(M):
    l, r, d = list(map(int, input().split()))
    if uf.find(l) == uf.find(r) and uf.diff(l, r) != d:
        ok = False
        break
    uf.unite(l, r, d)

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