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(id2, weight)
    @nodes[id2].add_edge(id1, weight)
  end

  def weight_dfs(id1, id2)
    dfs(id1, id2) do |w, n_id, on_id, 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
        cur_id = nid
        n = @nodes[cur_id]
        nid = @next_nodes[0][cur_id]
        weight += n.weights[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 }]
    dfs(root_id, nil, @next_nodes[0]) do |_w, n_id, on_id, 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

  # Depth First Search : 深さ優先探索
  def dfs(root_id, other_node_id, memo = {}, &block)
    visited = Set.new([root_id])
    @nodes[root_id].depth = 0
    stack = [root_id]
    while !stack.empty?
      n_id = stack.pop
      n = @nodes[n_id]
      n.weights.each do |on_id, w|
        next if visited.include?(on_id)
        visited << on_id
        @nodes[on_id].depth = n.depth + 1
        val = yield(w, n_id, on_id, memo)
        if on_id == other_node_id
          return val
        end
        stack.push(on_id)
      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_id, weight)
      @weights[other_node_id] = weight
    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[nid]
                  end
        break if nid == lca_id
      end
    end
    weight
  end
end

f = STDIN
tree = Tree.new
edge_color = {}
N, Q = f.gets.split(" ").map(&:to_i)
1.upto(N) { |i| tree.add_node(i) }
(N-1).times do
  n1, n2, c, d = f.gets.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(1)
Q.times do
  c, d, n1, n2 = f.gets.split(" ").map(&:to_i)
  puts tree.weight_lca2(n1, n2, edge_color[c], d)
end
f.close
