#include <iostream>
#include <vector>
#include <cmath>
#include <map>
#include <cstdio>

using namespace std;
typedef long long ll;

struct LCA {
private:
    ll n;
    ll m;
    vector<vector<ll>> parents;
    vector<ll> depths;

    void calc_parents_dfs(const vector<vector<ll>>& ns, ll cur, ll prev){
        if(prev != -1){
            depths.at(cur) = depths.at(prev) + 1;
        }else{
            depths.at(cur) = 0;
        }
        parents.at(cur).at(0) = cur;
        parents.at(cur).at(1) = prev;
        for(ll x : ns.at(cur)){
            if(x != prev){
                calc_parents_dfs(ns, x, cur);
            }
        }
    }
public:

    LCA(const vector<vector<ll>>& ns){
        n = ns.size();
        m = ceil(log2(n)) + 1;
        parents.resize(n);
        for(int i = 0; i < n; ++i){
            parents.at(i).resize(m);
        }
        depths.resize(n);
        calc_parents_dfs(ns, 0, -1);

        for(int k = 2; k < m; ++k){
            parents.at(0).at(k) = -1;
            for(int i = 1; i < n; ++i){
                ll p = parents.at(i).at(k - 1);
                if(p == -1){
                    parents.at(i).at(k) = -1;
                }else{
                    ll pp = parents.at(p).at(k - 1);
                    parents.at(i).at(k) = pp;
                }
            }
        }
    }

    ll get_parent(ll x, ll s){
        ll y = x;
        for(int i = 1; i < parents.at(x).size(); ++i){
            if(s % 2){
                y = parents.at(y).at(i);
            }
            s = s / 2;
        }
        return y;
    }

    ll get_lca(ll x, ll y){
        if(depths.at(x) < depths.at(y)){
            y = get_parent(y, depths.at(y) - depths.at(x));
        }else if(depths.at(y) < depths.at(x)){
            x = get_parent(x, depths.at(x) - depths.at(y));
        }
        if(x == y){ return x; }
        for(ll i = m - 1; i >= 0; i--){
            if(parents.at(x).at(i) != parents.at(y).at(i)){
                x = parents.at(x).at(i);
                y = parents.at(y).at(i);
            }
        }
        return parents.at(x).at(1);
    }
};

struct Edge {
    ll next;
    ll weight;
    ll color;
    Edge(ll n, ll w, ll c) : next(n), weight(w), color(c) {}
};

struct Query {
    ll x, y, u, v;
    Query(ll x, ll y, ll u, ll v) : x(x), y(y), u(u), v(v) {}
};

vector<vector<Edge>> ns;
vector<vector<ll>> ns2;
vector<Query> qs;

vector<ll> dists;
vector<map<ll, ll>> num_colors;
vector<map<ll, ll>> sum_colors;
vector<vector<ll>> q_cols;
vector<ll> tmp_nums;
vector<ll> tmp_sums;

void calc_dists(ll x, ll p){
    for(ll qc : q_cols.at(x)){
        num_colors.at(x).insert(make_pair(qc, tmp_nums.at(qc)));
        sum_colors.at(x).insert(make_pair(qc, tmp_sums.at(qc)));
    }
    for(auto e : ns.at(x)){
        if(e.next == p){ continue; }
        tmp_nums.at(e.color) += 1;
        tmp_sums.at(e.color) += e.weight;

        dists.at(e.next) = dists.at(x) + e.weight;
        calc_dists(e.next, x);

        tmp_nums.at(e.color) -= 1;
        tmp_sums.at(e.color) -= e.weight;
    }
}

int main(){
    ll n, q;
    cin >> n >> q;
    ns.resize(n);
    ns2.resize(n);
    for(int i = 0; i < n - 1; ++i){
        ll a, b, c, d;
        cin >> a >> b >> c >> d;
        a--; b--; c--;
        ns.at(a).push_back(Edge(b, d, c));
        ns.at(b).push_back(Edge(a, d, c));
        ns2.at(a).push_back(b);
        ns2.at(b).push_back(a);
    }

    LCA lca_calc(ns2);

    q_cols.resize(n);
    for(int i = 0; i < q; ++i){
        ll x, y, u, v;
        cin >> x >> y >> u >> v;
        x--; u--; v--;
        qs.push_back(Query(x, y, u, v));
        q_cols.at(u).push_back(x);
        q_cols.at(v).push_back(x);
        q_cols.at(lca_calc.get_lca(u, v)).push_back(x);
    }

    dists.resize(n, 0);
    num_colors.resize(n);
    sum_colors.resize(n);
    tmp_nums.resize(n, 0);
    tmp_sums.resize(n, 0);
    calc_dists(0, -1);

    for(auto q : qs){
        ll lca = lca_calc.get_lca(q.u, q.v);
        ll d = dists.at(q.u) + dists.at(q.v) - 2 * dists.at(lca);
        ll num_x = num_colors.at(q.u).at(q.x) + num_colors.at(q.v).at(q.x) - 2 * num_colors.at(lca).at(q.x);
        ll sum_x = sum_colors.at(q.u).at(q.x) + sum_colors.at(q.v).at(q.x) - 2 * sum_colors.at(lca).at(q.x);
        cout << d - sum_x + q.y * num_x << endl;
    }
    return 0;
}


Measured memory_bytes: 88620