#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
template<class T> using vc = vector<T>;
template<class T> using vvc = vector<vector<T>>;

#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define repe(i, l, r) for (ll i = (l); i < (r); i++)
#define reper(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define repa(i,n) for (auto& i: n)

template<class T> inline bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> inline bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
void init() {cin.tie(0);ios::sync_with_stdio(false);cout << fixed << setprecision(15);}

#ifdef DEBUG
template <class T, class N> void verr(const T& a, const N& n) { rep(i, n) cerr << a[i] << " "; cerr << "\n" << flush; }
ll dbgt = 1; void err() { cerr << "passed " << dbgt++ << "\n" << flush; }
template<class H, class... T> void err(H&& h,T&&... t){ cerr<< h << (sizeof...(t)?" ":"\n") << flush; if(sizeof...(t)>0) err(forward<T>(t)...); }
#endif

const ll INF = 4e18;
const ld EPS = 1e-11;
const ld PI = acos(-1.0L);
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
//--------------------------------------------------------------------------------//
// Lowest Common Ancestor by binary lifting
template <typename T>  // T: type of cost
struct LCA {
    struct edge{
        ll to, cost, color;
        edge(){}
        edge(ll _to, ll _color, T _cost = 0) : to(_to), color(_color), cost(_cost){};
    };
    
    ll n, root, max_pow;
    T unit;                     // 二項演算の単位元
    function<T(T, T)> op;       // costの二項演算
    vector<vector<edge>> E;     // 辺とそのコスト
    vector<ll> dep;             // 頂点の深さ
    vector<vector<edge>> par;   // ある頂点から2^kだけ遠い祖先とパスのコスト

    LCA(ll _n, function<T(T, T)> _op = [](T a, T b) { return a + b; }, T _unit = 0)
            : n(_n), E(_n), dep(_n), op(_op), unit(_unit) {
        max_pow = 0;
        while ((1 << max_pow) < n) max_pow++;
        par = vector<vector<edge>>(n + 1, vector<edge>(max_pow, edge(n, 0, unit)));
    }

    void addEdge(ll a, ll b, ll c, T d) {
        E[a].emplace_back(b, c, d);
    }

    void dfs(ll u, ll p, T c, ll d = 0) {
        if (p != -1) par[u][0].to = p;
        par[u][0].cost = c;
        dep[u] = d;
        for (ll i = 0; i < (ll)E[u].size(); i++) {
            ll v = E[u][i].to;
            if (v == p) continue;
            dfs(v, u, E[u][i].cost, d + 1);
        }
    }

    void build(ll _root = 0) {
        root = _root;
        dfs(root, -1, unit);
        for (ll i = 0; i < max_pow - 1; i++) {
            for (ll u = 0; u < n; u++) {
                edge nxt = par[par[u][i].to][i];
                par[u][i + 1] = edge(nxt.to, nxt.color, op(par[u][i].cost, nxt.cost));
            }
        }
    }
    // 頂点a,bのlca
    ll operator()(ll a, ll b) {
        if (dep[a] > dep[b]) swap(a, b);
        ll gap = dep[b] - dep[a];
        for (ll i = max_pow - 1; i >= 0; i--) {
            ll len = 1 << i;
            if (gap >= len) {
                gap -= len;
                b = par[b][i].to;
            }
        }
        if (a == b) return a;
        for (ll i = max_pow - 1; i >= 0; i--) {
            ll na = par[a][i].to;
            ll nb = par[b][i].to;
            if (na != nb){
                a = na, b = nb;
            }
        }
        return par[a][0].to;
    }
    // 頂点a, b間のパスの長さ
    ll plen(ll a, ll b) {
        ll c = LCA::operator()(a, b);
        return dep[a] + dep[b] - dep[c] * 2;
    }
    // 頂点a, b間のパスのコスト
    T pcost(ll a, ll b) {
        if (dep[a] > dep[b]) swap(a, b);
        T cost = unit;
        ll gap = dep[b] - dep[a];
        for (ll i = max_pow - 1; i >= 0; i--) {
            ll len = 1 << i;
            if (gap >= len) {
                gap -= len;
                cost = op(cost, par[b][i].cost);
                b = par[b][i].to;
            }
        }
        if (a == b) return cost;
        for (ll i = max_pow - 1; i >= 0; i--) {
            edge na = par[a][i];
            edge nb = par[b][i];
            if (na.to != nb.to){
                a = na.to, b = nb.to;
                cost = op(cost, op(na.cost, nb.cost));
            }
        }
        return op(cost, op(par[a][0].cost, par[b][0].cost));
    }
};
// LCA = lca(N, op, unit);  //頂点数N, costの二項演算(デフォルト:加算), 二項演算の単位元(デフォルト:0)

struct edg {
    ll d, c, id;
    edg() {}
    edg(ll d, ll c, ll i) : d(d), c(c), id(i) {}
};

int main() {
    init();
    ll N, Q;
    cin >> N >> Q;
    LCA<ll> lca(N);
    rep(i, N - 1) {
        ll a, b, c, d;
        cin >> a >> b >> c >> d;
        a--, b--, c--;
        lca.addEdge(a, b, c, d), lca.addEdge(b, a, c, d);
    }

    lca.build();

    vvc<edg> C(N - 1);
    rep(i, N - 1) C[i].eb(edg(0, 0, -1));
    vc<ll> IN(N, -1);
    ll cid = 0;

    auto dfs = [&](auto dfs, ll now, ll par) -> void {
        repa(p, lca.E[now]) {
            if (p.to == par) continue;
            IN[p.to] = cid;
            C[p.color].eb(p.cost, 1, cid), cid++;
            
            dfs(dfs, p.to, now);

            C[p.color].eb(-p.cost, -1, cid), cid++;
        }
    };

    dfs(dfs, 0, -1);

    rep(c, N - 1) {
        C[c].eb(edg(0, 0, 2 * N));
        repe(i, 1, C[c].size()){
            C[c][i].d += C[c][i - 1].d;
            C[c][i].c += C[c][i - 1].c;
        }
    }

    auto comp = [](const edg e1, const edg e2) { return bool(e1.id < e2.id); };
    rep(_, Q) {
        ll x, y, u, v;
        cin >> x >> y >> u >> v;
        x--, u--, v--;
        ll ans = lca.pcost(u, v), p = lca(u, v);

        ll ccnt = 0, cdist = 0;
        if (IN[u] > IN[v]) swap(u, v);

        auto it = C[x].begin(),
             itu = --upper_bound(all(C[x]), edg(-1, -1, IN[u]), comp),
             itv = --upper_bound(all(C[x]), edg(-1, -1, IN[v]), comp),
             itp = --upper_bound(all(C[x]), edg(-1, -1, IN[p]), comp);
        cdist = itu->d + itv->d - 2 * itp->d;
        ccnt  = itu->c + itv->c - 2 * itp->c;

        ans += ccnt * y - cdist;
        cout << ans << '\n';
    }

}

Measured memory_bytes: 80036