import sys

stdin = sys.stdin

 

sys.setrecursionlimit(10**5) 

 

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

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

def lf(): return list(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)]

        

    # ノードxのルートを求める

    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]

        

    # ノードxのルートからの距離を求める

    def weight(self, x:int) -> int:

        self.find(x)

        return self.diff_weight[x]

        

    # weight(y) - weight(x) = w となるようにする

    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は同じ木に属していません")





n,m = li()



lrd = []

for _ in range(m):

    l,r,d = li()

    l -= 1

    r -= 1

    lrd.append((l,r,d))

 

exist = True



wuf = WeightedUnionFind(n)



for l,r,d in lrd:

    wuf.unite(l,r,d)

    if wuf.diff(l,r) != d:

        exist = False

        break

    

if exist:

    print("Yes")

else:

    print("No")
import sys

stdin = sys.stdin

 

sys.setrecursionlimit(10**5) 

 

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

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

def lf(): return list(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())



n,m = li()



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

for _ in range(m):

    l,r,d = li()

    l -= 1

    r -= 1

    graph[l].append((d,r))

    graph[r].append((-d,l))

    

searched = [False]*n

dist = [float("inf") for _ in range(n)]



exist = True

for i in range(n):

    if not searched[i]:

        dist[i] = 0

        searched[i] = True

        stack = [(0,i)]

        

        while stack:

            cost, cur = stack.pop()

            for nex_cost, nex_node in graph[cur]:

                if searched[nex_node]:

                    if cost + nex_cost != dist[nex_node]:

                        exist = False

                        

                else:

                    stack.append((cost+nex_cost, nex_node))

                    dist[nex_node] = cost + nex_cost

                    searched[nex_node] = True

                    

if exist:

    print("Yes")

else:

    print("No")
import sys

stdin = sys.stdin
sys.setrecursionlimit(10**5)


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


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


def lf():
    return list(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)]

    # ノードxのルートを求める
    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]

    # ノードxのルートからの距離を求める
    def weight(self, x: int) -> int:
        self.find(x)
        return self.diff_weight[x]

    # weight(y) - weight(x) = w となるようにする
    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は同じ木に属していません")


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

import sys

stdin = sys.stdin
sys.setrecursionlimit(10**5)


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


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


def lf():
    return list(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())


n, m = li()
graph = [[] for _ in range(n)]
for _ in range(m):
    l, r, d = li()
    l -= 1
    r -= 1
    graph[l].append((d, r))
    graph[r].append((-d, l))
searched = [False] * n
dist = [float("inf") for _ in range(n)]
exist = True
for i in range(n):
    if not searched[i]:
        dist[i] = 0
        searched[i] = True
        stack = [(0, i)]
        while stack:
            cost, cur = stack.pop()
            for nex_cost, nex_node in graph[cur]:
                if searched[nex_node]:
                    if cost + nex_cost != dist[nex_node]:
                        exist = False
                else:
                    stack.append((cost + nex_cost, nex_node))
                    dist[nex_node] = cost + nex_cost
                    searched[nex_node] = True
if exist:
    print("Yes")
else:
    print("No")

-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)] - -    # ノードxのルートを求める -    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] - -    # ノードxのルートからの距離を求める -    def weight(self, x: int) -> int: -        self.find(x) -        return self.diff_weight[x] - -    # weight(y) - weight(x) = w となるようにする -    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は同じ木に属していません") - - -lrd = [] +graph = [[] for _ in range(n)] -    lrd.append((l, r, d)) +    graph[l].append((d, r)) +    graph[r].append((-d, l)) +searched = [False] * n +dist = [float("inf") for _ in range(n)] -wuf = WeightedUnionFind(n) -for l, r, d in lrd: -    wuf.unite(l, r, d) -    if wuf.diff(l, r) != d: -        exist = False -        break +for i in range(n): +    if not searched[i]: +        dist[i] = 0 +        searched[i] = True +        stack = [(0, i)] +        while stack: +            cost, cur = stack.pop() +            for nex_cost, nex_node in graph[cur]: +                if searched[nex_node]: +                    if cost + nex_cost != dist[nex_node]: +                        exist = False +                else: +                    stack.append((cost + nex_cost, nex_node)) +                    dist[nex_node] = cost + nex_cost +                    searched[nex_node] = True