#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define get_unique(x) x.erase(unique(all(x)), x.end());
typedef long long ll;
typedef complex<double> Complex;
const int INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;
template <class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
vector<T> make_vec(size_t a) {
    return vector<T>(a);
}
template <class T, class... Ts>
auto make_vec(size_t a, Ts... ts) {
    return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}

struct LowestCommonAncestor {
    int n, sn;
    vector<int> id, vs, dep;
    vector<pair<int, int>> node;
    LowestCommonAncestor(vector<vector<int>> g)
        : n(sz(g)), id(n), vs(n * 2 - 1), dep(n * 2 - 1) {
        int k = 0;
        dfs(0, -1, 0, k, g);
        sn = 1;
        while (sn < sz(dep)) {
            sn *= 2;
        }
        node.assign(2 * sn - 1, make_pair(INF, INF));
        for (int i = 0; i < sz(dep); i++) {
            node[sn + i - 1] = make_pair(dep[i], i);
        }
        for (int i = sn - 1; i >= 1; i--) {
            node[i] = min(node[i * 2 + 1], node[i * 2 + 2]);
        }
    }
    void dfs(int now, int pre, int d, int &k, const vector<vector<int>> &g) {
        id[now] = k;
        vs[k] = now;
        dep[k++] = d;
        for (int nxt : g[now]) {
            if (nxt == pre) continue;
            dfs(nxt, now, d + 1, k, g);
            vs[k] = now;
            dep[k++] = d;
        }
    }
    pair<int, int> query(int a, int b, int k = 0, int l = 0, int r = -1) {
        if (r < 0) r = sn;
        if (r <= a || b <= l) return make_pair(INF, INF);
        if (a <= l && r <= b) return node[k];
        auto vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
        auto vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
        return min(vl, vr);
    }
    int get(int u, int v) {
        int l = min(id[u], id[v]);
        int r = max(id[u], id[v]) + 1;
        return vs[query(l, r).second];
    }
    int depth(int u) {
        return dep[id[u]];
    }
};

struct edge {
    int to, color, len;
};

int n, q;
vector<vector<int>> G;
vector<vector<edge>> g;
vector<int> x, y, u, v;
vector<vector<int>> queries;
vector<int> num, sum, dist;
map<pair<int, int>, pair<int, int>> mp;
void dfs(int now, int pre, int d) {
    dist[now] = d;
    for (auto e : g[now]) {
        if (e.to == pre) continue;
        num[e.color]++;
        sum[e.color] += e.len;
        for (int x : queries[e.to]) {
            if (mp[make_pair(e.to, x)] != make_pair(0, 0)) continue;
            mp[make_pair(e.to, x)] = make_pair(num[x], sum[x]);
        }
        dfs(e.to, now, d + e.len);
        num[e.color]--;
        sum[e.color] -= e.len;
        for (int x : queries[e.to]) {
            if (mp[make_pair(e.to, x)] != make_pair(0, 0)) continue;
            mp[make_pair(e.to, x)] = make_pair(num[x], sum[x]);
        }
    }
}

int main() {
    cin >> n >> q;
    G.resize(n);
    g.resize(n);
    rep(i, n - 1) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        a--;
        b--;
        G[a].push_back(b);
        G[b].push_back(a);
        g[a].push_back((edge){b, c, d});
        g[b].push_back((edge){a, c, d});
    }
    LowestCommonAncestor lca(G);

    x.resize(q);
    y.resize(q);
    u.resize(q);
    v.resize(q);
    queries.resize(n);
    rep(i, q) {
        cin >> x[i] >> y[i] >> u[i] >> v[i];
        u[i]--;
        v[i]--;
        queries[u[i]].push_back(x[i]);
        queries[v[i]].push_back(x[i]);
        queries[lca.get(u[i], v[i])].push_back(x[i]);
    }

    sum.resize(n);
    num.resize(n);
    dist.resize(n);
    dfs(0, -1, 0);

    rep(i, q) {
        int ans = 0;
        {
            int NUM, SUM;
            tie(NUM, SUM) = mp[make_pair(u[i], x[i])];
            ans += dist[u[i]] - SUM + y[i] * NUM;
        }
        {
            int NUM, SUM;
            tie(NUM, SUM) = mp[make_pair(v[i], x[i])];
            ans += dist[v[i]] - SUM + y[i] * NUM;
        }
        {
            int l = lca.get(u[i], v[i]);
            int NUM, SUM;
            tie(NUM, SUM) = mp[make_pair(l, x[i])];
            ans -= 2 * (dist[l] - SUM + y[i] * NUM);
        }
        cout << ans << endl;
    }
}


Measured memory_bytes: 49624