#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef vector<ll> vl;
typedef pair<ll, ll> PP;
#define rep(i, n) for(ll i = 0; i < ll(n); i++)
#define all(v) v.begin(), v.end()
bool chmin(ll &a, ll b) {
    if(b < a) {
        a = b;
        return 1;
    }
    return 0;
}
bool chmax(ll &a, ll b) {
    if(b > a) {
        a = b;
        return 1;
    }
    return 0;
}
const ll INF = 999999999999999;
const ll MOD = 1000000007;
const ll MAX_N = 200010;
ll a, b, c, d, e, f, p, t, x, y, z, q, m, n, r, h, k, w, l, ans;
struct edge {
    ll to, cost, color;
};
vector<edge> g[MAX_N];
vl in2(MAX_N), par(MAX_N, -1), kyori(MAX_N, 0);
vector<PP> Vkazu[MAX_N], Vcost[MAX_N];
vl sz(MAX_N, -1), in(MAX_N), out(MAX_N), nxt(MAX_N, 0);
vl visited(MAX_N, 0);
vl kazu(MAX_N, 0), cost(MAX_N, 0);
void dfs(ll x) {
    in2[x] = p;
    visited[x] = 1;
    for(edge i : g[x]) {
        if(visited[i.to] == 0) {
            p++;
            par[i.to] = x;
            kazu[i.color]++;
            cost[i.color] += i.cost;
            Vkazu[i.color].push_back({p, kazu[i.color]});
            Vcost[i.color].push_back({p, cost[i.color]});
            kyori[i.to] = kyori[x] + i.cost;
            dfs(i.to);
            p++;
            kazu[i.color]--;
            cost[i.color] -= i.cost;
            Vkazu[i.color].push_back({p, kazu[i.color]});
            Vcost[i.color].push_back({p, cost[i.color]});
        }
    }
}

class HLD {
  public:
    vl G[MAX_N];

    void dfs_sz(ll v = 0) {
        sz[v] = 1;
        for(auto &u : G[v]) {
            dfs_sz(u);
            sz[v] += sz[u];
            if(sz[u] > sz[G[v][0]]) {
                swap(u, G[v][0]);
            }
        }
    }

    void dfs_hld(ll v = 0) {
        in[v] = t++;
        for(auto u : G[v]) {
            nxt[u] = (u == G[v][0] ? nxt[v] : u);
            dfs_hld(u);
        }
        out[v] = t;
    }

    void init(ll n, ll v = 0) {
        rep(i, n) {
            if(par[i] != -1)
                G[par[i]].push_back(i);
        }
        t = 0;
        visited = vl(MAX_N, 0);
        dfs_sz(v);
        dfs_hld(v);
    }

    /*void min_edge(ll u, ll v, ll k) {
        while (in[nxt[v]] != in[nxt[u]]) {
            if (in[u] > in[v]) swap(u, v);
            seg.update(in[nxt[v]] - 1, in[v], k);
            v = par[nxt[v]];
        }
        if (in[u] > in[v]) swap(u, v);
        seg.update(in[u], in[v], k);
    }
    ll min_edge_check(ll u, ll v) {
        k = INF;
        while (in[nxt[v]] != in[nxt[u]]) {
            if (in[u] > in[v]) swap(u, v);
            chmin(k, seg.query(in[nxt[v]] - 1, in[v]));
            v = par[nxt[v]];
        }
        if (in[u] > in[v]) swap(u, v);
        chmin(k, seg.query(in[u], in[v]));
        return k;
    }*/

    ll LCA(ll u, ll v) {
        while(in[nxt[v]] != in[nxt[u]]) {
            if(in[u] > in[v])
                swap(u, v);
            v = par[nxt[v]];
        }
        if(in[u] > in[v])
            swap(u, v);

        return u;
    }
};
int main() {
    cin >> n >> m;
    rep(i, n - 1) {
        cin >> a >> b >> c >> d;
        a--;
        b--;
        g[a].push_back((edge){b, d, c});
        g[b].push_back((edge){a, d, c});
    }

    rep(i, 100002) {
        Vkazu[i].push_back({0, 0});
        Vcost[i].push_back({0, 0});
    }

    p = 0;

    dfs(0);
    HLD hld;
    hld.init(n);

    rep(i, m) {
        cin >> x >> y >> z >> w;
        z--;
        w--;
        t = hld.LCA(z, w);
        a = lower_bound(all(Vcost[x]), make_pair(in2[z], INF)) - Vcost[x].begin() - 1;
        b = lower_bound(all(Vcost[x]), make_pair(in2[w], INF)) - Vcost[x].begin() - 1;
        c = lower_bound(all(Vcost[x]), make_pair(in2[t], INF)) - Vcost[x].begin() - 1;
        d = lower_bound(all(Vkazu[x]), make_pair(in2[z], INF)) - Vkazu[x].begin() - 1;
        e = lower_bound(all(Vkazu[x]), make_pair(in2[w], INF)) - Vkazu[x].begin() - 1;
        f = lower_bound(all(Vkazu[x]), make_pair(in2[t], INF)) - Vkazu[x].begin() - 1;
        cout << kyori[z] + kyori[w] - kyori[t] * 2 +
                    (Vkazu[x][d].second + Vkazu[x][e].second - Vkazu[x][f].second * 2) * y -
                    (Vcost[x][a].second + Vcost[x][b].second - Vcost[x][c].second * 2)
             << endl;
    }
}


Measured memory_bytes: 67552