# -*- coding: utf-8 -*-



"""

参考：https://www.hamayanhamayan.com/entry/2018/01/28/231916

・深さ優先

・幅優先とほとんど一緒だけど練習用にこっちも書いた。

"""



import sys



# 再帰呼び出しの回数制限(デフォルト1000)

sys.setrecursionlimit(10 ** 9)



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



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

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

for i in range(M):

    l, r, d = list(map(int, input().split()))

    l_edges[l-1].append((r-1, d))

    r_edges[r-1].append((l-1, d))



# 訪問済メモ

visited = [0] * N



def dfs(cur):

    visited[cur] = 1

    # 左から見た右側を確認

    for r, d in l_edges[cur]:

        # 訪問済なら矛盾がないか検証する

        if visited[r]:

            if pos[r] - pos[cur] != d:

                print('No')

                exit()

        # 未訪問なら今回の情報を記録する

        else:

            visited[r] = 1

            pos[r] = pos[cur] + d

            # 確認した位置を次の現在位置として見に行く

            dfs(r)

    # 右から見た左側を確認

    for l, d in r_edges[cur]:

        if visited[l]:

            if pos[cur] - pos[l] != d:

                print('No')

                exit()

        else:

            visited[l] = 1

            pos[l] = pos[cur] - d

            dfs(l)



for i in range(N):

    # 訪問済(確認済)でなければ走破しに行く

    if not visited[i]:

        # この開始位置を基準とした相対位置を記録する

        pos = {i: 0}

        dfs(i)

        pos = {}

# 最後まで矛盾がなければOK

print('Yes')

# -*- coding: utf-8 -*-



import sys



def input(): return sys.stdin.readline().strip()

def list2d(a, b, c): return [[c] * b for i in range(a)]

def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1): return int(-(-x // y))

def INT(): return int(eval(input()))

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

def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes(): print('Yes')

def No(): print('No')

def YES(): print('YES')

def NO(): print('NO')

sys.setrecursionlimit(10 ** 9)

INF = 10 ** 18

MOD = 10 ** 9 + 7



class WeightedUnionFind:

    """ 重み付きUnion-Find木 """



    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)

        # xの木の高さ < yの木の高さ

        if self.rank[rx] < self.rank[ry]:

            self.par[rx] = ry

            self.weight[rx] = w - self.weight[x] + self.weight[y]

        # xの木の高さ ≧ 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):

        """ xからyへのコスト """

        return self.weight[x] - self.weight[y]



N, M = MAP()

wuf = WeightedUnionFind(N)

for i in range(M):

    l, r, d = MAP()

    # 既に同じ集合にあるなら、距離が正しいか確認

    if wuf.same(l, r):

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

            No()

            exit()

    else:

        wuf.union(l, r, d)

Yes()

# -*- coding: utf-8 -*-
"""
参考：https://www.hamayanhamayan.com/entry/2018/01/28/231916
・深さ優先
・幅優先とほとんど一緒だけど練習用にこっちも書いた。
"""
import sys

# 再帰呼び出しの回数制限(デフォルト1000)
sys.setrecursionlimit(10**9)
N, M = list(map(int, input().split()))
l_edges = [[] for i in range(N)]
r_edges = [[] for i in range(N)]
for i in range(M):
    l, r, d = list(map(int, input().split()))
    l_edges[l - 1].append((r - 1, d))
    r_edges[r - 1].append((l - 1, d))
# 訪問済メモ
visited = [0] * N


def dfs(cur):
    visited[cur] = 1
    # 左から見た右側を確認
    for r, d in l_edges[cur]:
        # 訪問済なら矛盾がないか検証する
        if visited[r]:
            if pos[r] - pos[cur] != d:
                print("No")
                exit()
        # 未訪問なら今回の情報を記録する
        else:
            visited[r] = 1
            pos[r] = pos[cur] + d
            # 確認した位置を次の現在位置として見に行く
            dfs(r)
    # 右から見た左側を確認
    for l, d in r_edges[cur]:
        if visited[l]:
            if pos[cur] - pos[l] != d:
                print("No")
                exit()
        else:
            visited[l] = 1
            pos[l] = pos[cur] - d
            dfs(l)


for i in range(N):
    # 訪問済(確認済)でなければ走破しに行く
    if not visited[i]:
        # この開始位置を基準とした相対位置を記録する
        pos = {i: 0}
        dfs(i)
        pos = {}
# 最後まで矛盾がなければOK
print("Yes")

# -*- coding: utf-8 -*-
import sys


def input():
    return sys.stdin.readline().strip()


def list2d(a, b, c):
    return [[c] * b for i in range(a)]


def list3d(a, b, c, d):
    return [[[d] * c for j in range(b)] for i in range(a)]


def list4d(a, b, c, d, e):
    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]


def ceil(x, y=1):
    return int(-(-x // y))


def INT():
    return int(eval(input()))


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


def LIST(N=None):
    return list(MAP()) if N is None else [INT() for i in range(N)]


def Yes():
    print("Yes")


def No():
    print("No")


def YES():
    print("YES")


def NO():
    print("NO")


sys.setrecursionlimit(10**9)
INF = 10**18
MOD = 10**9 + 7


class WeightedUnionFind:
    """重み付きUnion-Find木"""

    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)
        # xの木の高さ < yの木の高さ
        if self.rank[rx] < self.rank[ry]:
            self.par[rx] = ry
            self.weight[rx] = w - self.weight[x] + self.weight[y]
        # xの木の高さ ≧ 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):
        """xからyへのコスト"""
        return self.weight[x] - self.weight[y]


N, M = MAP()
wuf = WeightedUnionFind(N)
for i in range(M):
    l, r, d = MAP()
    # 既に同じ集合にあるなら、距離が正しいか確認
    if wuf.same(l, r):
        if wuf.diff(l, r) != d:
            No()
            exit()
    else:
        wuf.union(l, r, d)
Yes()

-""" -参考：https://www.hamayanhamayan.com/entry/2018/01/28/231916 -・深さ優先 -・幅優先とほとんど一緒だけど練習用にこっちも書いた。 -""" -# 再帰呼び出しの回数制限(デフォルト1000) -sys.setrecursionlimit(10**9) -N, M = list(map(int, input().split())) -l_edges = [[] for i in range(N)] -r_edges = [[] for i in range(N)] -for i in range(M): -    l, r, d = list(map(int, input().split())) -    l_edges[l - 1].append((r - 1, d)) -    r_edges[r - 1].append((l - 1, d)) -# 訪問済メモ -visited = [0] * N + +def input(): +    return sys.stdin.readline().strip() -def dfs(cur): -    visited[cur] = 1 -    # 左から見た右側を確認 -    for r, d in l_edges[cur]: -        # 訪問済なら矛盾がないか検証する -        if visited[r]: -            if pos[r] - pos[cur] != d: -                print("No") -                exit() -        # 未訪問なら今回の情報を記録する -        else: -            visited[r] = 1 -            pos[r] = pos[cur] + d -            # 確認した位置を次の現在位置として見に行く -            dfs(r) -    # 右から見た左側を確認 -    for l, d in r_edges[cur]: -        if visited[l]: -            if pos[cur] - pos[l] != d: -                print("No") -                exit() -        else: -            visited[l] = 1 -            pos[l] = pos[cur] - d -            dfs(l) +def list2d(a, b, c): +    return [[c] * b for i in range(a)] -for i in range(N): -    # 訪問済(確認済)でなければ走破しに行く -    if not visited[i]: -        # この開始位置を基準とした相対位置を記録する -        pos = {i: 0} -        dfs(i) -        pos = {} -# 最後まで矛盾がなければOK -print("Yes") +def list3d(a, b, c, d): +    return [[[d] * c for j in range(b)] for i in range(a)] + + +def list4d(a, b, c, d, e): +    return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)] + + +def ceil(x, y=1): +    return int(-(-x // y)) + + +def INT(): +    return int(eval(input())) + + +def MAP(): +    return list(map(int, input().split())) + + +def LIST(N=None): +    return list(MAP()) if N is None else [INT() for i in range(N)] + + +def Yes(): +    print("Yes") + + +def No(): +    print("No") + + +def YES(): +    print("YES") + + +def NO(): +    print("NO") + + +sys.setrecursionlimit(10**9) +INF = 10**18 +MOD = 10**9 + 7 + + +class WeightedUnionFind: +    """重み付きUnion-Find木""" + +    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) +        # xの木の高さ < yの木の高さ +        if self.rank[rx] < self.rank[ry]: +            self.par[rx] = ry +            self.weight[rx] = w - self.weight[x] + self.weight[y] +        # xの木の高さ ≧ 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): +        """xからyへのコスト""" +        return self.weight[x] - self.weight[y] + + +N, M = MAP() +wuf = WeightedUnionFind(N) +for i in range(M): +    l, r, d = MAP() +    # 既に同じ集合にあるなら、距離が正しいか確認 +    if wuf.same(l, r): +        if wuf.diff(l, r) != d: +            No() +            exit() +    else: +        wuf.union(l, r, d) +Yes()