#include <bits/stdc++.h>
#define int long long
#define mod (int)(1e9+7)
#define inf (int)(3e18)
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,n) for(int i=1;i<n;i++)
#define P pair<int,int>
#define PiP pair<int,pair<int,int>>
#define all(v) v.begin(),v.end()
#define mkp make_pair
#define mkt make_tuple
#define prique(T) priority_queue<T,vector<T>,greater<T>>
#define vecunique(vec) sort(vec.begin(), vec.end());decltype(vec)::iterator result = std::unique(vec.begin(), vec.end());vec.erase(result, vec.end())
using namespace std;
template<class T> inline void chmax(T& a, T b) { a = max(a, b); }
template<class T> inline void chmin(T& a, T b) { a = min(a, b); }

bool prime(int x) {
	for (int i = 2; i * i <= x; i++) {
		if (x % i == 0)return false;
	}
	return x > 1;
}
int gcd(int x, int y) {
	if (y == 0)return x;
	return gcd(y, x % y);
}
int lcm(int x, int y) {
	return x / gcd(x, y) * y;
}
int kai(int x, int y) {
	int res = 1;
	for (int i = x - y + 1; i <= x; i++) {
		res *= i; res %= mod;
	}
	return res;
}
int mod_pow(int x, int y) {
	int res = 1;
	while (y > 0) {
		if (y & 1) {
			res = res * x % mod;
		}
		x = x * x % mod;
		y >>= 1;
	}
	return res;
}
int comb(int x, int y) {
	if (y > x)return 0;
	return kai(x, y) * mod_pow(kai(y, y), mod - 2) % mod;
}
/*--------Library Zone!--------*/

int n, q;
int par[50][114514], depth[114514];
int dist[114514];
struct info {
	int to, co, lo;
};
struct info2 {
	int co, lo, x, y;
};
vector<info>ed[114514];
vector<int>need[114514];
vector<info2>query(114514);
map<int, int>sumlong[114514], sumhon[114514];
int nowlong[114514], nowhon[114514];
void dfs(int x) {
	for (info i : ed[x]) {
		if (depth[i.to] == -1) {
			depth[i.to] = depth[x] + 1;
			par[0][i.to] = x;
			dist[i.to] = dist[x] + i.lo;
			dfs(i.to);
		}
	}
}
void init() {
	fill(depth, depth + n, -1); depth[0] = 0;
	dfs(0);
	rep(i, 30)rep(j, n) {
		if (par[i][j] == -1)par[i + 1][j] = -1;
		else par[i + 1][j] = par[i][par[i][j]];
	}
}
int lca(int x, int y) {
	if (depth[x] > depth[y])swap(x, y);
	for (int i = 30; i >= 0; i--) {
		if ((depth[y] - depth[x]) >> i & 1) {
			y = par[i][y];
		}
	}
	if (x == y)return x;
	for (int i = 30; i >= 0; i--) {
		if (par[i][x] != par[i][y]) {
			x = par[i][x]; y = par[i][y];
		}
	}
	return par[0][x];
}
void dfs2(int x, int bef) {
	for (int i : need[x]) {
		sumlong[x][i] = nowlong[i];
		sumhon[x][i] = nowhon[i];
	}
	for (info i : ed[x]) {
		if (i.to == bef)continue;
		nowlong[i.co] += i.lo;
		nowhon[i.co]++;
		dfs2(i.to, x);
		nowlong[i.co] -= i.lo;
		nowhon[i.co]--;
	}
}
signed main() {
	cin >> n >> q;
	rep(i, n - 1) {
		int a, b, c, d; cin >> a >> b >> c >> d; a--; b--; c--;
		ed[a].push_back({ b,c,d });
		ed[b].push_back({ a,c,d });
	}
	init();
	rep(i, q) {
		cin >> query[i].co >> query[i].lo >> query[i].x >> query[i].y; query[i].x--; query[i].y--; query[i].co--;
		need[query[i].x].push_back(query[i].co);
		need[query[i].y].push_back(query[i].co);
		need[lca(query[i].x, query[i].y)].push_back(query[i].co);
	}
	dfs2(0, 0);
	rep(i, q) {
		int bef = dist[query[i].x] + dist[query[i].y] - dist[lca(query[i].x, query[i].y)] * 2;
		int mai = sumlong[query[i].x][query[i].co] + sumlong[query[i].y][query[i].co] - sumlong[lca(query[i].x, query[i].y)][query[i].co] * 2;
		int plus = sumhon[query[i].x][query[i].co] + sumhon[query[i].y][query[i].co] - sumhon[lca(query[i].x, query[i].y)][query[i].co] * 2;
		cout << bef - mai + plus * query[i].lo << endl;
	}
}


Measured memory_bytes: 97716