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 in Python (3.4.3) (judge verdict: Accepted)

# coding:utf-8

import sys


input = sys.stdin.readline


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


# ---
class UnionFind:
    __slots__ = ['nodes', 'weight']

    def __init__(self, size: int) -> None:
        self.nodes = [-1] * size  # ノードの値が負の場合ルートを表し、値は木のランクを表す
        self.weight = [0] * size  # ノードx -> ルート(ノードx)への重みを表す

    # 検索
    def find(self, x: int) -> int:
        if self.nodes[x] < 0:
            return x
        else:
            parent = self.find(self.nodes[x])
            self.weight[x] += self.weight[self.nodes[x]]
            self.nodes[x] = parent
            return parent

    # 併合
    # def unite(self, x: int, y: int, w: int) -> bool:
    #     root_x = self.find(x)
    #     root_y = self.find(y)
    #     if root_x == root_y:
    #         return False
    #     else:
    #         rank_x = -self.nodes[root_x]
    #         rank_y = -self.nodes[root_y]
    #         if rank_x < rank_y:
    #             self.nodes[root_x] = root_y
    #             self.weight[root_x] = w - self.weight[y] - self.weight[x]
    #         else:
    #             self.nodes[root_y] = root_x
    #             self.weight[root_y] = w - self.weight[x] - self.weight[y]
    #
    #             if rank_x == rank_y:
    #                 self.nodes[root_x] += -1
    #
    #         return True

    # xとyのルートが等しい時: 入力された重みwが正しいかどうかを判定
    # xとyのルートが異なる時: xとyを併合する
    # True: 併合，False: 何もしない，ValueError: 入力された重みに矛盾がある
    def relate(self, x: int, y: int, w: int) -> bool:
        root_x = self.find(x)
        root_y = self.find(y)
        if root_x == root_y:
            # 入力された重みwに矛盾がないか判定
            if self.weight[x] - self.weight[y] == w:
                return False
            raise ValueError
        else:
            rank_x = -self.nodes[root_x]
            rank_y = -self.nodes[root_y]
            if rank_x < rank_y:
                self.nodes[root_x] = root_y
                self.weight[root_x] = w + self.weight[y] - self.weight[x]
            else:
                self.nodes[root_y] = root_x
                self.weight[root_y] = -w + self.weight[x] - self.weight[y]

                if rank_x == rank_y:
                    self.nodes[root_x] += -1
            return True

    # UnionFind木の一覧を返す
    # def get_tree(self) -> dict:
    #     tree = {}
    #     for i, node in enumerate(self.nodes):
    #         if node < 0:
    #             if i not in tree.keys():
    #                 tree[i] = []
    #         else:
    #             if self.find(node) in tree.keys():
    #                 tree[self.find(node)].append(i)
    #             else:
    #                 tree[self.find(node)] = [i]
    # 
    #     return tree


N, M = inpl()
uf = UnionFind(N)
relate = uf.relate
try:
    for i in range(M):
        l, r, d = inpl()
        relate(l - 1, r - 1, d)
    else:
        print('Yes')
except ValueError:
    print('No')