#include<bits/stdc++.h>

using namespace std;

int const maxn = 1e5 + 5, logg = 18, maxc = 5e6;
vector < vector < int > > g[maxn];
int dp[maxn][logg], h[maxn], pref[maxn], lef[maxn], righ[maxn], cur = 1;
pair < int, int > lst[maxn];
vector < int > a;
int nxtl[maxc], nxtr[maxc], node[maxn];
vector < pair < int, int > > R[maxc];
vector < int > suff[maxc];
vector < vector < int > > add[maxn];
int min_lef[maxc], max_lef[maxc];

void dfs(int v, int p) {
    h[v] = h[p] + 1, lef[v] = (int)a.size();
    a.push_back(v);
    dp[v][0] = p;
    for (int i = 1; i < logg; ++i) dp[v][i] = dp[dp[v][i - 1]][i - 1];
    for (auto u : g[v]) {
        if (u[0] != p) {
            pref[u[0]] = pref[v] + u[2], dfs(u[0], v);
            add[u[1]].push_back({lef[u[0]], righ[u[0]], u[2]});
        }
    }
    righ[v] = (int)a.size();
    a.push_back(v);
}

inline int get_la(int v, int x) {
    for (int i = 0; i < logg; ++i) {
        if ((x&(1 << i)) > 0) v = dp[v][i];
    }
    return v;
}

inline int get_lca(int u, int v) {
    if (h[u] > h[v]) u = get_la(u, h[u] - h[v]);
    else v = get_la(v, h[v] - h[u]);
    if (u == v) return u;
    for (int i = logg - 1; i >= 0; --i) {
        if (dp[v][i] != dp[u][i]) v = dp[v][i], u = dp[u][i];
    }
    return dp[v][0];
}

void build(int i, int v, int l, int r) {
    if (r - l == 1) {
        min_lef[i] = add[v][l][0], max_lef[i] = min_lef[i];
        R[i] = {{add[v][l][1], add[v][l][2]}};
        suff[i] = {add[v][l][2]};
        return;
    }
    int m = (r + l) / 2;
    nxtl[i] = cur++, nxtr[i] = cur++;
    build(nxtl[i], v, l, m);
    build(nxtr[i], v, m, r);
    min_lef[i] = min(min_lef[nxtl[i]], min_lef[nxtr[i]]);
    max_lef[i] = max(max_lef[nxtl[i]], max_lef[nxtr[i]]);
    R[i].resize(r - l);
    merge(R[nxtl[i]].begin(), R[nxtl[i]].end(), R[nxtr[i]].begin(), R[nxtr[i]].end(), R[i].begin());
    int sum = 0;
    for (int j = (int)R[i].size() - 1; j >= 0; --j) {
        sum += R[i][j].second;
        suff[i].push_back(sum);
    }
    reverse(suff[i].begin(), suff[i].end());
}

inline pair < int, int > gett(int i, int l, int r, int lq, int rq, int righ) {
    //if (lq == 5 && rq == 6) cout << l << " " << r << " " << min_lef[i] << " " << max_lef[i] << endl;
    if (min_lef[i] >= rq || max_lef[i] < lq) return {0, 0};
    if (lq <= min_lef[i] && max_lef[i] < rq) {
        pair < int, int > d = {righ, -1};
        int pos = lower_bound(R[i].begin(), R[i].end(), d) - R[i].begin();
        if (pos == (int)R[i].size()) return {0, 0};
        return {suff[i][pos], (int)R[i].size() - pos};
    }
    int m = (r + l) / 2;
    pair < int, int > s1 = gett(nxtl[i], l, m, lq, rq, righ);
    pair < int, int > s2 = gett(nxtr[i], m, r, lq, rq, righ);
    return {s1.first + s2.first, s1.second + s2.second};
}

inline int get(int u, int v, int c, int d) {
    if (u == v || (int)add[c].size() == 0) return 0;
    pair < int, int > s = gett(node[c], 0, (int)add[c].size(), lef[u] + 1, lef[v] + 1, righ[v]);
    return d * s.second - s.first;
}

main() {
#ifdef HOME
    freopen("input.txt", "r", stdin);
#endif // HOME
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n, q, u, v, c, d;
    cin >> n >> q;
    for (int i = 1; i < n; ++i) {
        cin >> u >> v >> c >> d;
        g[u].push_back({v, c, d});
        g[v].push_back({u, c, d});
    }
    dfs(1, 0);
    for (int i = 1; i < n; ++i) {
        node[i] = cur++;
        sort(add[i].begin(), add[i].end());
        if ((int)add[i].size() != 0) build(node[i], i, 0, (int)add[i].size());
    }
    for (int i = 1; i <= q; ++i) {
        cin >> c >> d >> u >> v;
        int t = get_lca(u, v), ans = pref[u] + pref[v] - 2 * pref[t];
        ans += get(t, u, c, d);
        ans += get(t, v, c, d);
        cout << ans << '\n';
    }
    return 0;
}



Measured memory_bytes: 316964