package main

import (
  "bufio"
  "os"
  "strconv"
  "strings"
  "fmt"
)

var reader = bufio.NewReaderSize(os.Stdin, 1000000)
var writer = bufio.NewWriter(os.Stdout)
func NextLine() string {
  buffer := make([]byte, 0)
  for true {
    line, isPrefix, err := reader.ReadLine()
    if err != nil { panic(err) }
    buffer = append(buffer, line...)
    if !isPrefix { break }
  }
  return string(buffer)
}
func NextInt(A ...*int) {
  L := strings.Split(NextLine(), " ")
  for i, a := range A {
    *a, _ = strconv.Atoi(L[i])
  }
}
func NextIntVec(A *[]int) {
  L := strings.Split(NextLine(), " ")
  (*A) = make([]int, len(L))
  for i, l := range L {
    (*A)[i], _ = strconv.Atoi(l)
  }
}
func NextFloat(A ...*float64) {
  L := strings.Split(NextLine(), " ")
  for i, a := range A {
    *a, _ = strconv.ParseFloat(L[i], 64)
  }
}
func NextFloatVec(A *[]float64) {
  L := strings.Split(NextLine(), " ")
  (*A) = make([]float64, len(L))
  for i, l := range L {
    (*A)[i], _ = strconv.ParseFloat(l, 64)
  }
}
func Write(s interface{}) {
  fmt.Fprintln(writer, s)
}
func WriteIntVec(A []int) {
  S := make([]string, len(A))
  for i, a := range A {
    S[i] = strconv.Itoa(a)
  }
  Write(strings.Join(S, " "))
}
func Output() {
  _ = writer.Flush()
}

func MaxInt(A ...int) int {
  max := A[0]
  for _, a := range A {
    if max < a { max = a }
  }
  return max
}
func MinInt(A ...int) int {
  min := A[0]
  for _, a := range A {
    if a < min { min = a }
  }
  return min
}
func SumInt(A ...int) int {
  sum := 0
  for _, a := range A {
    sum += a
  }
  return sum
}
func AbsInt(x int) int {
  if x < 0 { x = -x }
  return x
}

func DFS(T, C *[][][]int, F, D*[]int, P *[][]int, cnt *int, u int) {
  for _, adj := range (*T)[u] {
    v, c, d := adj[0], adj[1], adj[2]
    if (*F)[v] <= (*cnt) { continue }
    (*cnt)++
    (*F)[v] = (*cnt)
    (*D)[v] = (*D)[u] + 1
    (*P)[v][0] = u
    (*C)[0] = append((*C)[0], []int{(*cnt), (*C)[0][len((*C)[0]) - 1][1] + d})
    (*C)[c] = append((*C)[c], []int{(*cnt), (*C)[c][len((*C)[c]) - 1][1] + d, (*C)[c][len((*C)[c]) - 1][2] + 1})
    DFS(T, C, F, D, P, cnt, v)
    (*cnt)++
    (*C)[0] = append((*C)[0], []int{(*cnt), (*C)[0][len((*C)[0]) - 1][1] - d})
    (*C)[c] = append((*C)[c], []int{(*cnt), (*C)[c][len((*C)[c]) - 1][1] - d, (*C)[c][len((*C)[c]) - 1][2] - 1})
  }
}

func Parent(P *[][]int, u, n int) int {
  if n == 0 { return u }
  k := 0
  for _n := n; _n % 2 < 1 ; _n /= 2 { k++ }
  return Parent(P, (*P)[u][k], n - 1 << uint(k))
}

func LCA(P *[][]int, D *[]int, u, v, s int) int {
  p, q := u, v
  if (*D)[u] < (*D)[v] {
    q = Parent(P, v, (*D)[v] - (*D)[u])
  } else {
    p = Parent(P, u, (*D)[u] - (*D)[v])
  }
  if p == q { return p }
  for i := s; 0 <= i; i-- {
    if (*P)[p][i] != (*P)[q][i] { return LCA(P, D, (*P)[p][i], (*P)[q][i], i) }
  }
  return (*P)[p][0]
}

func Search(C [][]int, s int) []int {
  N := len(C)
  if C[N - 1][0] <= s { return C[N - 1] }
  les, gts := 0, N - 1
  for 1 < gts - les {
    med := (gts + les) / 2
    if s < C[med][0] {
      gts = med
    } else {
      les = med
    }
  }
  return C[les]
}

func Dist(C *[][][]int, F *[]int, u, x, y int) int {
  f := (*F)[u]
  Z := Search((*C)[x], f)
  return Search((*C)[0], f)[1] - Z[1] + Z[2] * y
}

func Solve() {
  var N, Q int
  NextInt(&N, &Q)
  T := make([][][]int, N)
  for i := range T {
    T[i] = make([][]int, 0)
  }
  var a, b, c, d int
  for i := 1; i < N; i++ {
    NextInt(&a, &b, &c, &d)
    a, b = a - 1, b - 1
    T[a] = append(T[a], []int{b, c, d})
    T[b] = append(T[b], []int{a, c, d})
  }
  C := make([][][]int, N)
  for i := range C {
    C[i] = make([][]int, 0)
    C[i] = append(C[i], []int{0,0,0})
  }
  F := make([]int, N)
  for i := range F[1:] {
    F[i + 1] = 2 * N
  }
  D := make([]int, N)
  k := 1
  for n := 1; n < N; n *= 2 { k++ }
  P := make([][]int, N)
  for i := range P {
    P[i] = make([]int, k)
  }
  cnt := 0
  DFS(&T, &C, &F, &D, &P, &cnt, 0)
  for i := 1; i < k; i++ {
    for u := range P {
      P[u][i] = P[P[u][i - 1]][i - 1]
    }
  }
  var x, y, u, v int
  for i := 0; i < Q; i++ {
    NextInt(&x, &y, &u, &v)
    u, v = u - 1, v - 1
    r := LCA(&P, &D, u, v, len(P[u]) - 1)
    Write(Dist(&C, &F, u, x, y) + Dist(&C, &F, v, x, y) - 2 * Dist(&C, &F, r, x, y))
  }
}

func main() {
  Solve()
  Output()
}

Measured memory_bytes: 123904