#include <bits/stdc++.h>
using namespace std;

template<typename T>
void out(T x) { cout << x << endl; exit(0); }
#define watch(x) cout << (#x) << " is " << (x) << endl





using ll = long long;

const ll mod = 1e9+7;
const int maxn = 1e5 + 5;
const int LOG = 19;


struct query {
    ll color, value;
    int u, v;
    void read() {
	cin>>color>>value>>u>>v;
	--u; --v;
    }
};

int n, q;
int par[LOG+1][maxn];
int dep[maxn];
vector<pair<int,int>> g[maxn];
ll color[maxn], len[maxn];

query qu[maxn];
vector<int> en[maxn];
ll cnt[maxn]; // for query i, how many of it's colored edge does it have
ll acc[maxn]; // for query i, what's the sum of lengths


void dfs(int at, int p=0) {
    for (int j=1; j<LOG; j++) {
	par[j][at] = par[j-1][par[j-1][at]];
    }
    for (auto ed: g[at]) {
	int to = ed.second;
	if (to==p) continue;
	dep[to] = 1+dep[at];
	par[0][to] = at;
	dfs(to, at);
    }
}

int lca(int u, int v) {
    if (dep[u] < dep[v]) swap(u, v);
    int dx = dep[u] - dep[v];
    for (int j=0; j<LOG; j++) {
	if (dx>>j&1) {
	    u = par[j][u];
	}
    }
    if (u == v) return u;

    for (int j=LOG-1; j>=0; j--) {
	if (par[j][u] != par[j][v]) {
	    u = par[j][u];
	    v = par[j][v];
	}
    }

    return par[0][u];
}


vector<ll> pathsum;
vector<pair<int,ll>> colors[maxn]; // (dep, len)

void go(int at, int p=0) {
    
    for (int qi: en[at]) {
	
	int oth = (at^qu[qi].u^qu[qi].v);
	int mid = lca(oth, at);
	int qcol = qu[qi].color;


	// {
	//     watch(at+1);
	//     watch(qcol);
	//     for (auto pp: colors[qcol]) {
	// 	cout<<"("<<pp.first<<" "<<pp.second<<") ";
	//     }
	//     cout<<endl;
	// }
	
	if (dep[at] > 0) {
	    // watch(mid+1);
	    // watch(dep[mid]);
	    auto iter = std::prev(std::upper_bound(colors[qcol].begin(), colors[qcol].end(), make_pair(dep[mid],-1ll)));
	    cnt[qi] += int(colors[qcol].size())-1-(iter-colors[qcol].begin());
	    // cout<<"!!! "<<at+1<<endl;
	    // watch(mid+1);
	    // watch(dep[mid]);
	    // watch(iter-colors[qcol].begin());
	    // cout<<at<<": "<<cnt[qi]<<endl;
		
	    assert(pathsum.size());
	    ll rm = colors[qcol].back().second - iter->second;
	    acc[qi] -= rm;	    
	    acc[qi] += (pathsum.back() - (dep[mid] > 0 ? pathsum[dep[mid]-1] : 0));
	}
    }
    
    for (auto ed: g[at]) {
	int to = ed.second;
	if (to == p) continue;
	int eId = ed.first;
	pathsum.push_back(len[eId] + (pathsum.empty() ? 0 : pathsum.back()));
	colors[color[eId]].push_back({dep[at], colors[color[eId]].back().second + len[eId]});
	go(to, at);
	pathsum.pop_back();
	colors[color[eId]].pop_back();
    }
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);

    cin>>n>>q;
    for (int i=0; i<n-1; i++) {
	int u,v;
	cin>>u>>v>>color[i]>>len[i];
	--u;--v;
	g[u].push_back({i,v});
	g[v].push_back({i,u});
    }

    dfs(0);


    for (int i=0; i<q; i++) {
	qu[i].read();
    }


    for (int i=0; i<q; i++) {
	int u = qu[i].u;
	int v = qu[i].v;
	//cout<<u+1<<" "<<v+1<<": "<<mid+1<<endl;
	en[u].push_back(i);
	en[v].push_back(i);
    }

    for (int i=1; i<=n-1; i++) {
	colors[i].push_back(make_pair(-1, 0));
    }

    go(0);

    for (int i=0; i<q; i++) {
	//watch(cnt[i]);
	ll res = cnt[i]*qu[i].value + acc[i];
	cout<<res<<"\n";
    }

            
    
    return 0;
}


Measured memory_bytes: 44004