#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define REP(i, n) FOR(i, 0, (n))
#define FOR(i, a, b) for(int i=(a); i<(b); i++)
#define LAR(a, b) ((a)=max((a),(b)))
#define SML(a, b) ((a)=min((a),(b)))
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pair<int, int>> vpii;
typedef pair<int, int> pii;
#define PB push_back
#define EB emplace_back
#ifdef LOCAL_DEBUG
#define DEBUG(...) printf(__VA_ARGS__)
#else
#define DEBUG(...)
#endif

#define N 112345
struct edge {
	int from, to, c, d;
} NUL = {0, 0, 0, 0};
vector<edge> g[N];
int s[N]; //size
int d[N]; //depth
edge pe[N];
vi cte[N];
void dfa(int a, const edge &e, int dep=0){
	DEBUG("dfa(%d, {%d=>%d, %d, %d}, %d)\n", a+1, e.from+1, e.to+1, e.c, e.d, dep);
	pe[a] = e;
	cte[e.c].EB(a);
	d[a] = dep;
	s[a] = 1;
	for(edge &i : g[a]) if(i.to != e.from){
		dfa(i.to, i, dep+1);
		s[a] += s[i.to];
	}
}
int q[N];
vi seq[N];
void dfb(int a, int qq){
	DEBUG("dfb(%d, %d)\n", a+1, qq+1);
	q[a] = qq;
	seq[qq].EB(a);
	int mx = -1;
	for(edge &i : g[a]) if(i.to != pe[a].from){
		if(mx==-1 || s[mx] < s[i.to]){
			mx = i.to;
		}
	}
	if(mx == -1) return;
	dfb(mx, qq);
	for(edge &i : g[a]) if(i.to != pe[a].from && i.to != mx){
		dfb(i.to, i.to);
	}
}
int r[N], t[N];

class BIT
{
public:
    vector<int> bit;
    int M;

    BIT(int M):
        bit(vector<int>(M+1, 0)), M(M) {}

    int sum(int i) {
        if (!i) return 0;
        return bit[i] + sum(i-(i&-i));
    }

    void add(int i, int x) {
        if (i > M) return;
        bit[i] += x;
        add(i+(i&-i), x);
    }
};
BIT db(N), cb(N); 

int clc(int a, BIT &b){
	int ret = 0;
	while(a){
		int c = q[a];
		ret += b.sum(r[a]) - b.sum(r[c]-1);
		a = pe[c].from;
	}
	return ret;
}

struct query {
	int i, x, y, u, v;
};
vector<query> ctq[N]; // color index -> query
int ans[N];

#define M 17
int ps[N][M]={};
int lca(int u, int v){
	if(d[u] > d[v]) swap(u, v);
	int dd = d[v] - d[u];
	for(int i = M-1; i>=0; i--){
		if(dd & (1<<i)){
			v = ps[v][i];
		}
	}
	if(u==v) return u;
	for(int i = M-1; i>=0; i--){
		if(ps[u][i] != ps[v][i]){
			u = ps[u][i];
			v = ps[v][i];
		}
	}
	return ps[u][0];
}

int n;
void prt(){
#ifdef LOCAL_DEBUG
	DEBUG("  ");
	FOR(i, 1, n+1) DEBUG("%4d ", i); DEBUG("\n");
	DEBUG("  ");
	FOR(i, 1, n+1) DEBUG("%4d ", t[i]+1); DEBUG("\n");
	FOR(i, 1, n+1) DEBUG("%4d ", db.sum(i)-db.sum(i-1)); DEBUG("\n");
	FOR(i, 1, n+1) DEBUG("%4d ", cb.sum(i)-cb.sum(i-1)); DEBUG("\n");
#endif
}

int main(){
	int q; scanf("%d%d", &n, &q);
	REP(i, n-1){
		int a, b, c, d; 
		scanf("%d%d%d%d", &a, &b, &c, &d);
		a--; b--;
		g[a].PB({a, b, c, d});
		g[b].PB({b, a, c, d});
	}
	dfa(0, NUL);
	dfb(0, 0);
	FOR(i, 1, n) ps[i][0] = pe[i].from;
	FOR(j, 1, M){
		REP(i, n){
			ps[i][j] = ps[ps[i][j-1]][j-1];
		}
	}
	DEBUG("Doubled\n");
	int tmp = 1;
	for(vi &v : seq){
		REP(i, (int)v.size()){
			int j = v[i];
			r[j] = tmp + i;
			t[tmp + i] = j;
		}
		tmp += v.size();
	}
	REP(i, n) DEBUG("%d => %d\n", i+1, r[i]);
	FOR(i, 1, n){
		db.add(r[i], pe[i].d);
		DEBUG("adding to %d\n", r[i]);
	}
	prt();
	REP(i, q){
		int x, y, u, v; scanf("%d%d%d%d", &x, &y, &u, &v); u--; v--;
		ctq[x].PB({i, x, y, u, v});
	}
	DEBUG("Finished reading query\n");
	REP(i, N){
		if(!cte[i].size() && !ctq[i].size())  continue;
		DEBUG("color = %d\n", i);
		for(int j : cte[i]){
			edge &e = pe[j];
			db.add(r[e.to], -e.d);
			cb.add(r[e.to], 1);
		}
		// prt();
		for(query &q : ctq[i]){
			int w = lca(q.u, q.v);
			int d = clc(q.u, db) + clc(q.v, db) - clc(w, db) * 2;
			int e = clc(q.u, cb) + clc(q.v, cb) - clc(w, cb) * 2;
			ans[q.i] = d + e * q.y;
			DEBUG("%d=>%d, lca=%d, d=%d, cnt=%d\n", q.u+1, q.v+1, w+1, d, e);
		}
		for(int j : cte[i]){
			edge &e = pe[j];
			db.add(r[e.to], e.d);
			cb.add(r[e.to], -1);
		}
		// prt();
		DEBUG("=====\n");
	}
	REP(i, q) printf("%d\n", ans[i]);
}


Measured memory_bytes: 38260