import java.io.*
import java.util.*
import java.lang.Math.*


class LCA(val N: Int) {
    private val to = Array(N){ArrayList<Int>()}
    private val co = Array(N){ArrayList<Long>()}
    private val dep = IntArray(N){0}
    private val costs = LongArray(N){0}
    private var l = 0
    private val par = Array(N+1){ArrayList<Int>()}
    private var root = 0
    init {
        while ((1 shl l) < N) {
            l++
        }
        par.forEach { it.addAll(List(this.l){0}) }
    }
    fun addEdge(s: Int, t: Int, cost: Long=1L) {
        to[s].add(t)
        co[s].add(cost)
        to[t].add(s)
        co[t].add(cost)
    }
    private fun dfs(x: Int, d: Int=0, cost: Long=0L, p: Int=-1) {
        if (p != -1) {
            this.par[x][0] = p
        }
        this.dep[x] = d
        this.costs[x] = cost
        for (i in 0 until to[x].size) {
            val u = this.to[x][i]
            if (u == p)
                continue
            else
                dfs(u, d+1, cost+this.co[x][i], x)
        }
    }
    fun biuld(root: Int = 0) {
        this.root = root
        dfs(root)
        for (i in 0 until this.l - 1) {
            for (x in 0 until N) {
                this.par[x][i+1] = par[par[x][i]][i]
            }
        }
    }
    fun lca(a: Int, b: Int): Int {
        var a = a; var b = b
        if (dep[a] > dep[b]) {
            a = b.also{b = a}
        }
        var gap = dep[b] - dep[a]
        for (i in this.l - 1 downTo 0) {
            val len = 1 shl i
            if (gap >= len) {
                gap -= len
                b = par[b][i]
            }
        }
        if (a == b) {
            return a
        }
        for (i in this.l-1 downTo 0) {
            val na = par[a][i]
            val nb = par[b][i]
            if (na != nb) {
                a = na; b = nb
            }
        }
        return par[a][0]
    }
    fun length(a: Int, b: Int): Int {
        val c = lca(a, b)
        return dep[a] + dep[b] - dep[c] * 2
    }
    fun distance(a: Int, b: Int, common: Int=-1): Long {
        val c = if (common<0) this.lca(a, b) else common
        return costs[a] + costs[b] - costs[c] * 2
    }
}


fun main() {
    val (N,Q) = rd.readIntArray()
    val gr = LCA(N)
    val egs = Array(N){ArrayList<To>()}
    for (i in 0 until N-1) {
        var (a, b, col, dst) = rd.readIntArray()
        a--;b--
        egs[a].add(To(b, dst.toLong(), col))
        egs[b].add(To(a, dst.toLong(), col))
        gr.addEdge(a, b, dst.toLong())
    }
    gr.biuld()

    data class Query(val cx: Int, val qid: Int, val coeff: Int, val dy: Long)
    val ans = LongArray(Q){0}
    val qrys = Array(N){ArrayList<Query>()}
    for (q in 0 until Q) {
        var (cx, dy, a, b) = rd.readIntArray()
        a--; b--

        val lca = gr.lca(a, b)
        ans[q] = gr.distance(a, b, lca)

        qrys[a].add(Query(cx, q, 1, dy.toLong()))
        qrys[b].add(Query(cx, q, 1, dy.toLong()))
        qrys[lca].add(Query(cx, q, -2, dy.toLong()))
    }

    val cnt = IntArray(N){0}
    val sum = LongArray(N){0L}

    fun dfs(v: Int, p: Int=-1) {
        for (qr in qrys[v]) {
            val (col,qid, coeff, dist) = qr
            var x = -sum[col]
            x += dist * cnt[col]
            ans[qid] += x * coeff
        }

        for (eg in egs[v]) {
            val (to, cost, col) = eg
            if (to == p) continue

            cnt[col] += 1
            sum[col] += cost
            dfs(to, v)
            cnt[col] -= 1
            sum[col] -= cost
        }
    }

    dfs(0)
    for (q in 0 until Q) {
        println(ans[q])
    }
}


//val rd = debug.Reader("abc", "171", "f", "sample-1")
val rd = Reader()
fun main(args: Array<String>) {
    Thread(null, MainThread(), "mainThread", 128 * 1024 * 1024).start()
}


const val MOD = 1_000_000_007L; const val INF = Int.MAX_VALUE/2; const val LINF = Long.MAX_VALUE/2
const val EPS = 1e-9; fun DBLEQ(a: Double, b: Double): Boolean {return abs(a - b) < EPS}
data class IntPair(val first: Int, val second: Int)
data class To(val idx: Int, val cost: Long, val col: Int)
fun <T>edge(V: Int): Array<ArrayList<T>> { return Array(V){ArrayList<T>()} }
val errPrintln: (Any) -> Unit = { msg -> System.err.println(msg) }
class MainThread : Runnable {
    override fun run() { main() }
}
class Reader {
    private val br = BufferedReader(InputStreamReader(System.`in`))
    val readString: () -> String = { br.readLine() }
    val readInt: () -> Int = { br.readLine().toInt() }
    val readLong: () -> Long = { br.readLine().toLong() }
    val readIntArray: () -> IntArray = { br.readLine().split(' ').map { it.toInt() }.toIntArray() }
    val readLongArray: () -> LongArray = { br.readLine().split(' ').map { it.toLong() }.toLongArray() }
    val readListInt: () -> List<Int> = { br.readLine().split(' ').map { it.toInt() } }
    val readListLong: () -> List<Long> = { br.readLine().split(' ').map { it.toLong() } }
}


Measured memory_bytes: 171680