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 Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    int N = scanner.nextInt();
    int M = scanner.nextInt();


    UnionFind uf = new UnionFind(N);
    HashMap<Integer, PointSet> map = new HashMap<>();
    for (int i = 0; i < N; i++) {
      PointSet ps = new PointSet(i);
      map.put(i, ps);
    }

    for (int i = 0; i < M; i++) {
      int left = scanner.nextInt() - 1;
      int right = scanner.nextInt() - 1;
      int dist = scanner.nextInt();

      if(uf.find(left) == uf.find(right)) {
        int g = uf.find(left);
        int d = map.get(g).get(right).pos - map.get(g).get(left).pos;
        if (d != dist) {
          System.out.println("No");
          return;
        }
      } else {
        int lg = uf.find(left);
        int[] newGroups = uf.union(left, right);
        int fg = newGroups[1];
        int tg = newGroups[0];

        int from = left, to = right, d = dist;
        if (lg != fg) {
          from = right;
          to = left;
          d = -dist;
        }

        int newPos = map.get(tg).get(to).pos - d;
        int oldPos = map.get(fg).get(from).pos;
        int delta = newPos - oldPos;
        for (Point p : map.get(fg).list) {
          p.pos += delta;
        }
        map.get(tg).addAll(map.get(fg));
      }
    }

    System.out.println("Yes");
  }

  static class UnionFind {
    private final int[] table;
    private final int[] ranks;
    private final int[] sizes;

    public UnionFind(int size) {
      this.table = new int[size];
      this.ranks = new int[size];
      this.sizes = new int[size];
      for (int i = 0; i < size; i++) {
        table[i] = i;
        sizes[i] = 1;
      }
    }

    public int find(int x) {
      if (table[x] != x) {
        table[x] = find(table[x]);
      }
      return table[x];
    }

    public int[] union(int x, int y) {
      int xRoot = find(x);
      int yRoot = find(y);
      if (xRoot == yRoot) return null;

      if (ranks[xRoot] < ranks[yRoot]) {
        int tmp = xRoot;
        xRoot = yRoot;
        yRoot = tmp;
      }

      table[yRoot] = xRoot;
      sizes[xRoot] += sizes[yRoot];
      if (ranks[xRoot] == ranks[yRoot]) ranks[xRoot]++;
      return new int[]{xRoot, yRoot};
    }
  }

  static class PointSet {
    List<Point> list = new ArrayList<>();
    HashMap<Integer, Point> map = new HashMap<>();

    public PointSet(int id) {
      Point p = new Point(id);
      list.add(p);
      map.put(id, p);
    }

    public void addAll(PointSet set) {
      list.addAll(set.list);
      map.putAll(set.map);
      Collections.sort(list);
    }

    public Point get(int id) {
      return map.get(id);
    }
  }

  static class Point implements Comparable<Point> {
    public final int id;
    public int pos;

    Point(int id) {
      this.id = id;
    }

    @Override public int compareTo(Point o) {
      return pos - o.pos;
    }
  }
}