def numba_compile(numba_config):
    import os, sys
    if sys.argv[-1] == "ONLINE_JUDGE":
        from numba import njit
        from numba.pycc import CC
        cc = CC("my_module")
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature)(func)
            cc.export(func.__name__, signature)(func)
        cc.compile()
        exit()
    elif os.name == "posix":
        exec(f"from my_module import {','.join(func.__name__ for func, _ in numba_config)}")
        for func, _ in numba_config:
            globals()[func.__name__] = vars()[func.__name__]
    else:
        from numba import njit
        for func, signature in numba_config:
            globals()[func.__name__] = njit(signature, cache=True)(func)
        print("compiled!", file=sys.stderr)

class HLD:
    # HL 分解
    # 検証1 (distance) 閉路: https://atcoder.jp/contests/abc014/submissions/13991240
    # 検証2 (lca) [yosupo] Lowest Common Ancestor: https://judge.yosupo.jp/submission/12490
    def __init__(self, E, root=1):
        # E は双方向に辺を張った木で、破壊的に有向グラフに変更される
        # O(N)
        self.E = E
        self.root = root
        self.N = N = len(E)  # 頂点数
        self.Parent = [-1] * N  # 頂点番号 v -> 親ノード
        self.Size = [-1] * N  # 頂点番号 v -> 部分木のサイズ
        self.dfs1()

        self.Mapping = [-1] * N  # 頂点番号 v -> 内部インデックス
        self.Head = list(range(N))  # 頂点番号 v -> v を含む heavy path の左端の頂点番号
        self.Depth = [0] * N  # 頂点番号 v -> 深さ（root から v までの距離）
        self.dfs2()

    def dfs1(self):
        E = self.E
        Parent, Size = self.Parent, self.Size
        Path = [self.root]
        Idx_edge = [0]
        while Path:
            v = Path[-1]
            idx_edge = Idx_edge[-1]
            Ev = E[v]
            if idx_edge != len(Ev):
                # 行きがけ・通りがけ 辺の数だけ実行される
                u = Ev[idx_edge]
                Idx_edge[-1] += 1
                E[u].remove(v)  # 有向グラフならここをコメントアウトする
                Parent[u] = v
                Path.append(u)
                Idx_edge.append(0)
            else:
                # 帰りがけ 頂点の数だけ実行される
                if len(Ev) >= 2:
                    ma = -1
                    argmax = None
                    for i, u in enumerate(Ev):
                        if Size[u] > ma:
                            ma = Size[u]
                            argmax = i
                    u0, um = Ev[0], Ev[argmax]
                    Size[u0], Size[um] = Size[um], Size[u0]
                    Ev[0], Ev[argmax] = Ev[argmax], Ev[0]
                Size[v] = sum(Size[u] for u in Ev) + 1
                Path.pop()
                Idx_edge.pop()

    def dfs2(self):
        E = self.E
        Mapping = self.Mapping
        Head = self.Head
        Depth = self.Depth
        k = 0
        St = [self.root]
        while St:
            v = St.pop()
            Mapping[v] = k
            k += 1
            Ev = E[v]
            if Ev:
                Head[Ev[0]] = Head[v]
                St += Ev[::-1]
                for u in Ev:
                    Depth[u] = Depth[v] + 1  # distance を使わないのならここをコメントアウトする

    def lca(self, v, u):
        # O(logN)
        Parent = self.Parent
        Mapping = self.Mapping
        Head = self.Head
        while True:
            if Mapping[v] > Mapping[u]:
                v, u = u, v  # v の方を根に近くする
            if Head[v] == Head[u]:
                return v
            u = Parent[Head[u]]

    def distance(self, v, u):
        # O(logN)
        Depth = self.Depth
        return Depth[v] + Depth[u] - 2 * Depth[self.lca(v, u)]

    def get_for_each_edge(self, v, u, identity, merge, func):
        Mapping = self.Mapping
        Head = self.Head
        Parent = self.Parent
        res = identity
        while True:
            if Mapping[v] > Mapping[u]:
                v, u = u, v
            if Head[u] != Head[v]:
                res = merge(res, func(Mapping[Head[u]], Mapping[u]+1))
                u = Parent[Head[u]]
            else:
                if v != u:
                    res = merge(res, func(Mapping[v]+1, Mapping[u]+1))
                return res

# >>> binary indexed tree >>>
# 必要な要素数+1 の長さの ndarray の 1 要素目以降を使う
def bitify(arr):  # [bitify, "void(i8[:])"],
    # len(arr) は 2 冪 + 1
    for i in range(1, len(arr)-1):
        arr[i + (i & -i)] += arr[i]
def bit_sum(bit, i):  # [bit_sum, "i8(i8[:],i8)"],
    # (0, i]
    res = 0
    while i:
        res += bit[i]
        i -= i & -i
    return res
def bit_add(bit, i, val):  # [bit_add, "void(i8[:],i8,i8)"],
    n = len(bit)
    while i < n:
        bit[i] += val
        i += i & -i
# <<< binary indexed tree <<<

numba_compile([
    [bitify, "void(i8[:])"],
    [bit_sum, "i8(i8[:],i8)"],
    [bit_add, "void(i8[:],i8,i8)"],
])

import sys
from operator import itemgetter, add
from itertools import groupby
from functools import partial
import numpy as np

def main():
    N, Q = map(int, sys.stdin.buffer.readline().split())
    m = list(map(int, sys.stdin.buffer.read().split()))
    ABCD, XYUV = m[:(N-1)*4], m[(N-1)*4:]
    G = [[] for _ in range(N+1)]
    for a, b in zip(ABCD[::4], ABCD[1::4]):
        G[a].append(b)
        G[b].append(a)
    hld = HLD(G)
    weights = [0] * (1<<N.bit_length())
    colors = [[] for _ in range(N)]
    m = iter(ABCD)
    for a, b, c, d in zip(m, m, m, m):
        v, u = hld.Mapping[a], hld.Mapping[b]
        edge = (v if v > u else u) + 1
        weights[edge] = d
        colors[c].append(edge)
    bit = np.array(weights, dtype=np.int64)
    bitify(bit)
    bit_add_ = partial(bit_add, bit)
    bit_sum_ = partial(bit_sum, bit)
    m = iter(XYUV)
    IXYUV = sorted(zip(range(Q), m, m, m, m), key=itemgetter(1))
    Ans = [0] * Q
    base = 1<<32
    mask = base-1
    for x, group in groupby(IXYUV, key=itemgetter(1)):
        for edge in colors[x]:
            bit_add_(edge, base-weights[edge])
        for i, _, y, u, v in group:
            a = hld.get_for_each_edge(u, v, 0, add, lambda p, q: bit_sum_(q)-bit_sum_(p))
            a = (a>>32) * y + (a&mask)
            Ans[i] = a
        for edge in colors[x]:
            bit_add_(edge, weights[edge]-base)
    print("\n".join(map(str, Ans)))

main()


Measured memory_bytes: 120708