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 Ruby (2.3.3) (judge verdict: Accepted)

class Node
  attr_accessor :parent, :rank, :diff_weight

  def initialize
    @parent = -1 # Positive value means its parent,and Negative value means its size.
    @rank = 0
    @diff_weight = 0
  end
end

class UnionFindTree
  
  def initialize(n)
    @nodes = (0...n).to_a.map { |i| Node.new }
  end

  def find(x)
    
    if @nodes[x].parent < 0
      x
    else
      y = find(@nodes[x].parent)
      @nodes[x].diff_weight += @nodes[@nodes[x].parent].diff_weight # 累積和をとる
      @nodes[x].parent = y
    end
  end

  def unite(a, b, w)
    
    # x と y それぞれについて、 root との重み差分を補正
    # p weight(b)
    w += weight(a)
    w -= weight(b)
    
    a = find(a)
    b = find(b)
    
    return w == diff(a, b) ? true : false if a == b

    if @nodes[a].rank < @nodes[b].rank
      @nodes[b].parent += @nodes[a].parent
      @nodes[a].parent = b
      @nodes[a].diff_weight = -w
    else
      @nodes[a].parent += @nodes[b].parent
      @nodes[b].parent = a
      @nodes[a].rank += 1 if @nodes[a].rank == @nodes[b].rank
      @nodes[b].diff_weight = w
    end
    
    
  end
  
  # def unite(a, b)
  # 
  #   a = find(a)
  #   b = find(b)
  #   return if a == b
  # 
  #   if @nodes[a].rank < @nodes[b].rank
  #     @nodes[b].parent += @nodes[a].parent
  #     @nodes[a].parent = b
  #   else
  #     @nodes[a].parent += @nodes[b].parent
  #     @nodes[b].parent = a
  #     @nodes[a].rank += 1 if @nodes[a].rank == @nodes[b].rank
  #   end
  # end

  def same?(a, b)
    find(a) == find(b)
  end
  
  def size(a)
    -@nodes[find(a)].parent
  end
  
  def weight(x)
    find(x); # 経路圧縮
    return @nodes[x].diff_weight;
  end
  
  def diff(x, y)
    return nil unless same?(x, y) # つながってなければ距離を測れないのでnilを返すことにした(2019/03/10)
    weight(y) - weight(x)
  end
  
  # 確認用。アルゴリズムとは関係無い
  def parents 
    @nodes.map(&:parent)
  end
end

# class Bridge
#   attr_accessor :first, :second

#   def initialize
#     @first = nil
#     @second = nil
#   end
  
#   def nodes=(a)
#     a[0], a[1] = a[1], a[0] if a[0] > a[1]
#     @first = a[0]
#     @second = a[1]
#   end
  
# end

n, m = gets.split.map(&:to_i)

uft = UnionFindTree.new(n)

m.times do |i|
  
  query = gets.split.map(&:to_i)
  if true
    a, b, w = query
    a -= 1
    b -= 1
    if !uft.unite(b,a,w)
      puts "No"
      exit
    end  
    # p uft
  elsif query[0] == 1
    a, b = query[1,2]
    puts uft.diff(a, b) || ??
  else
    p "Error!"
  end
end

puts "Yes"

# bridges = (0...M).to_a.map { Bridge.new }

# M.times do |i|
#   bridge = gets.split.map(&:to_i)
#   bridge.map! { |n| n - 1 }
#   bridges[i].nodes = bridge
# end
# p bridges

# ans = Array.new(M, 0)

# inco = N * ( N - 1 ) / 2 # inconvenience

# n = N
# q = M

# uft = UnionFindTree.new(n)

# q.times do |i|
  
#   j = (M-1)-i
#   ans[j] = inco
  
#   x, y = bridges[j].first, bridges[j].second
  
#   inco -= uft.size(x) * uft.size(y) if !uft.same?(x, y)
#   break if inco == 0
  
#   uft.unite(x, y)
# end

# puts ans