#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;

struct LowestCommonAncestor {
    const int root, UB;
    int n;
    std::vector<std::vector<int>> adj, par;
    std::vector<int> dep;

    explicit LowestCommonAncestor(int _n, int _r = 0) :
        root(_r), UB(log2(_n) + 1), n(_n), adj(n),
        par(UB, std::vector<int>(n)), dep(n) {}

    void add_edge(int u, int v) { adj[u].push_back(v); adj[v].push_back(u); }

    void Preprocessing() {
        Dfs(root, -1, 0);
        for (int k = 0; k + 1 < UB; ++k)
            for (int v = 0; v < n; ++v)
                par[k + 1][v] = (par[k][v] < 0 ? -1 : par[k][par[k][v]]);
    }

    void Dfs(int cur, int p, int d) {
        par[0][cur] = p;
        dep[cur] = d;
        for (const int dst : adj[cur])
            if (dst != p) Dfs(dst, cur, d + 1);
    }

    int query(int u, int v) {
        if (dep[u] > dep[v]) std::swap(u, v);
        for (int k = 0; k < UB; ++k)
            if ((dep[v] - dep[u]) >> k & 1) v = par[k][v];
        if (u == v) return u;
        for (int k = UB - 1; 0 <= k; --k)
            if (par[k][u] != par[k][v]) { u = par[k][u]; v = par[k][v]; }
        return par[0][u];
    }
};

struct Info {
    int q_id, color, mul;
    Info() {}
    Info(int _q, int _c, int _m) : q_id(_q), color(_c), mul(_m) {}
};

struct Edge {
    int dst, color, len;
    Edge() {}
    Edge(int _d, int _c, int _l) : dst(_d), color(_c), len(_l) {}
};

int N, Q;
vector<ll> q_len;
vector<ll> ans;
vector<vector<Edge>> adj;
vector<vector<Info>> info;

void distFromRoot(int pre, int cur, ll d, vector<ll> &d_root) {
    d_root[cur] = d;
    for (const auto &e : adj[cur]) {
        if (e.dst != pre) distFromRoot(cur, e.dst, d + e.len, d_root);
    }
}

void Dfs(int pre, int cur, map<int, ll> &dist_color, map<int, int> &num_color) {
    for (const auto i : info[cur]) {
        ll add = i.mul * q_len[i.q_id] * num_color[i.color] - i.mul * dist_color[i.color];
        ans[i.q_id] += add;
    }

    for (const auto &e : adj[cur]) {
        if (e.dst != pre) {
            dist_color[e.color] += e.len;
            num_color[e.color] += 1;

            Dfs(cur, e.dst, dist_color, num_color);

            dist_color[e.color] -= e.len;
            num_color[e.color] -= 1;
        }
    }
}

int main() {
    cin.tie(0); ios::sync_with_stdio(false);
    // cout << setprecision(8) << setiosflags(ios::fixed);

    cin >> N >> Q;

    adj.resize(N);
    info.resize(N);

    LowestCommonAncestor lca(N);
    for (int i = 0; i + 1 < N; ++i) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        --a; --b; --c;
        adj[a].emplace_back(Edge(b, c, d));
        adj[b].emplace_back(Edge(a, c, d));
        lca.add_edge(a, b);
    }
    lca.Preprocessing();

    vector<ll> d_root(N);
    distFromRoot(-1, 0, 0, d_root);

    q_len.resize(Q);
    info.resize(N);
    ans.resize(Q);
    for (int i = 0; i < Q; ++i) {
        // 色，辺の長さ，二頂点
        int u, v, c;
        cin >> c >> q_len[i] >> u >> v;
        --c; --u; --v;

        int p = lca.query(u, v);
        ans[i] = d_root[u] + d_root[v] - 2 * d_root[p];

        info[u].emplace_back(Info(i, c, 1));
        info[v].emplace_back(Info(i, c, 1));
        info[p].emplace_back(Info(i, c, -2));
    }

    map<int, ll> dist_color;
    map<int, int> num_color;
    Dfs(-1, 0, dist_color, num_color);

    for (int i = 0; i < Q; ++i) cout << ans[i] << '\n';

    return 0;
}


Measured memory_bytes: 47096