Problem:
Score : 600 points

Problem Statement

There is a tree with N vertices numbered 1 to N.
The i-th edge in this tree connects Vertex a_i and Vertex b_i, and the color and length of that edge are c_i and d_i, respectively.
Here the color of each edge is represented by an integer between 1 and N-1 (inclusive). The same integer corresponds to the same color, and different integers correspond to different colors.

Answer the following Q queries:

Query j (1 \leq j \leq Q): assuming that the length of every edge whose color is x_j is changed to y_j, find the distance between Vertex u_j and Vertex v_j. (The changes of the lengths of edges do not affect the subsequent queries.)

Constraints

2 \leq N \leq 10^5

1 \leq Q \leq 10^5

1 \leq a_i, b_i \leq N

1 \leq c_i \leq N-1

1 \leq d_i \leq 10^4

1 \leq x_j \leq N-1

1 \leq y_j \leq 10^4

1 \leq u_j < v_j \leq N

The given graph is a tree.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N Q
a_1 b_1 c_1 d_1
:
a_{N-1} b_{N-1} c_{N-1} d_{N-1}
x_1 y_1 u_1 v_1
:
x_Q y_Q u_Q v_Q

Output

Print Q lines. The j-th line (1 \leq j \leq Q) should contain the answer to Query j.

Sample Input 1

5 3
1 2 1 10
1 3 2 20
2 4 4 30
5 2 1 40
1 100 1 4
1 100 1 5
3 1000 3 4

Sample Output 1

130
200
60

The graph in this input is as follows:

Here the edges of Color 1 are shown as solid red lines, the edge of Color 2 is shown as a bold green line, and the edge of Color 4 is shown as a blue dashed line.

Query 1: Assuming that the length of every edge whose color is 1 is changed to 100, the distance between Vertex 1 and Vertex 4 is 100 + 30 = 130.

Query 2: Assuming that the length of every edge whose color is 1 is changed to 100, the distance between Vertex 1 and Vertex 5 is 100 + 100 = 200.

Query 3: Assuming that the length of every edge whose color is 3 is changed to 1000 (there is no such edge), the distance between Vertex 3 and Vertex 4 is 20 + 10 + 30 = 60. Note that the edges of Color 1 now have their original lengths.

Solution in Ruby (2.3.3) (judge verdict: Time Limit Exceeded)

require "set"

class Tree
  def initialize
    @nodes = {}
  end

  def add_node(id)
    @nodes[id] ||= Node.new(id)
  end

  def add_edge(id1, id2, weight = 1)
    @nodes[id1].add_edge(@nodes[id2], weight)
    @nodes[id2].add_edge(@nodes[id1], weight)
  end

  def weight_dfs(id1, id2)
    @nodes[id1].dfs(@nodes[id2]) do |w, n, on, memo|
      memo[n.id] ||= 0
      memo[on.id] = memo[n.id] + w
    end
  end

  def weight_lca(id1, id2)
    lca_id = lca(id1, id2)
    weight = 0
    # id1/id2 -> lca_idの距離の和
    [id1, id2].each do |id|
      next if id == lca_id
      nid = id
      loop do
        n = @nodes[nid]
        nid = @next_nodes[0][nid]
        weight += n.weights[@nodes[nid]]
        break if nid == lca_id
      end
    end
    weight
  end

  # Lowest Common Ancestor : 最小共通祖先
  def lca_setup(root_id = nil)
    root_id ||= @nodes.values.first.tap { |n| n.depth = 0 }.id
    n = @nodes.size
    @log_n = Math.log2(n).floor
    # next_nodes[0]の計算
    @next_nodes = [{ root_id => -1 }]
    @nodes[root_id].dfs(nil, @next_nodes[0]) do |_w, n, on, memo|
      memo[on.id] = n.id
    end
    # next_nodes[1〜log_n-1]の計算
    0.upto(@log_n - 1) do |k|
      @next_nodes[k + 1] = {}
      @nodes.keys.each do |i|
        nid = @next_nodes[k][i]
        if nid == -1
          @next_nodes[k + 1][i] = -1
        else
          @next_nodes[k + 1][i] = @next_nodes[k][nid]
        end
      end
    end
  end

  def lca_next(id, step)
    nid = id
    @log_n.downto(0) do |k|
      return -1 if nid == -1
      if ((step >> k) & 1) == 1
        nid = @next_nodes[k][nid]
      end
    end
    nid
  end

  def lca(id1, id2)
    n1 = @nodes[id1]
    n2 = @nodes[id2]
    # depthを合わせる
    if n1.depth != n2.depth
      n1, n2 = [n1, n2].sort_by { |n| n.depth }.reverse
      new_n1_id = lca_next(n1.id, n1.depth - n2.depth)
      n1 = @nodes[new_n1_id]
    end
    return n1.id if n1.id == n2.id
    # 探索
    loop do
      ([@log_n, Math.log2(n1.depth).floor].min).downto(0) do |k|
        if @next_nodes[k][n1.id] != @next_nodes[k][n2.id]
          n1 = @nodes[@next_nodes[k][n1.id]]
          n2 = @nodes[@next_nodes[k][n2.id]]
          break
        elsif k.zero?
          return @next_nodes[k][n1.id]
        end
      end
    end
  end

  class Node
    attr_reader :id, :weights
    attr_accessor :depth
    def initialize(id)
      @id = id
      @depth = nil
      @weights = {}
    end

    def add_edge(other_node, weight)
      @weights[other_node] = weight
    end

    # Depth First Search : 深さ優先探索
    def dfs(other_node, memo = {}, &block)
      visited = Set.new
      @depth = 0
      stack = [self]
      while !stack.empty?
        n = stack.pop
        visited << n.id
        n.weights.each do |on, w|
          next if visited.include?(on.id)
          on.depth = n.depth + 1
          val = yield(w, n, on, memo)
          if on == other_node
            return val
          end
          stack.push(on)
        end
      end
    end
  end
end

class Tree
  def weight_lca2(id1, id2, edges, overwrite_w)
    lca_id = lca(id1, id2)
    weight = 0
    # id1/id2 -> lca_idの距離の和
    [id1, id2].each do |id|
      next if id == lca_id
      nid = id
      loop do
        cur_id = nid
        nid = @next_nodes[0][nid]
        n = @nodes[cur_id]
        n1, n2 = [cur_id, nid].sort
        weight += if edges && edges[n1] && edges[n1].include?(n2)
                    overwrite_w
                  else
                    n.weights[@nodes[nid]]
                  end
        break if nid == lca_id
      end
    end
    weight
  end
end

f = STDIN
tree = Tree.new
edge_color = {}
N, Q = f.gets.chomp.split(" ").map(&:to_i)
1.upto(N) { |i| tree.add_node(i) }
(N-1).times do
  n1, n2, c, d = f.gets.chomp.split(" ").map(&:to_i)
  tree.add_edge(n1, n2, d)
  edge_color[c] ||= {}
  ns, nl = [n1, n2].sort
  edge_color[c][ns] ||= Set.new
  edge_color[c][ns] << nl
end

tree.lca_setup
Q.times do
  c, d, n1, n2 = f.gets.chomp.split(" ").map(&:to_i)
  puts tree.weight_lca2(n1, n2, edge_color[c], d)
end
f.close