N, Q = gets.chomp.split(" ").map(&:to_i)
E = Hash.new{|h, k| h[k] = []}
C = Hash.new{|h, k| h[k] = []}
(N - 1).times{|n|
  a, b, c, d = gets.chomp.split(" ").map(&:to_i)
  E[a] << [b, c, d, n]
  E[b] << [a, c, d, n]
}
M = []
Q.times{
  M << gets.chomp.split(" ").map(&:to_i)
}

D = Hash.new{|h, k| h[k] = Array.new}
stk = []
V = Hash.new{|h, k| h[k] = [0, 0, []]}
stk.push([1, 0, 0, 0, 0])
V[1] = [0, 0, 0, []]
until(stk.empty?) do
  xv, xc, xdp, xd, dd = stk.pop
  D[xdp] << xv
  C[xc] << [xv, dd]
  E[xv].each{|a, c, d|
    next if V.include?(a)
    V[a] = [xd + d, c, xdp + 1, []]
    dpth = 1
    while(xdp + 1 - dpth >= 0) do
      V[a][3] << D[xdp + 1 - dpth][-1]
      dpth <<= 1
    end
    stk.push([a, c, xdp + 1, xd + d, d])
  }
end

def get_upper_depth(a, dpth)
  df = V[a][2] - dpth
  return a if df == 0
  i = 0
  while(2 ** i < df) do
    i += 1
  end
  return V[a][3][i] if 2 ** i == df
  return get_upper_depth(V[a][3][i-1], dpth)
end

def get_same_depth(a, b)
  da = V[a][2]
  db = V[b][2]
  return get_same_depth(a, get_upper_depth(b, da)) if da < db
  return get_same_depth(b, get_upper_depth(a, db)) if da > db
  return [V[a][0], V[a][2]] if V[a][0] == V[b][0]
  return [V[a][3][0], V[a][2] - 1] if V[a][3][0] == V[b][3][0]
  return [V[a][3][1], V[a][2] - 2] if V[a][3][1] == V[b][3][1]
  (2...V[a][3].size).each{|i|
    return get_same_depth(V[a][3][i - 1], V[b][3][i - 1]) if V[a][3][i] == V[b][3][i]
  }
  return get_same_depth(V[a][3][-1], V[b][3][-1])
end

M.each{|x, y, u, v|
  ans = V[u][0] + V[v][0]
  ma, md = get_same_depth(u, v)
  ans -= (V[ma][0] * 2)
  C[x].each{|c, dd|
    dc = V[c][2]
    if md < dc && dc <= V[u][2] then
      ans += (y - dd) if c == get_upper_depth(u, dc)
    end
    if md < dc && dc <= V[v][2] then
      ans += (y - dd) if c == get_upper_depth(v, dc)
    end
  }
  puts ans
}
