#include <bits/stdc++.h>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) begin(v),end(v)
#define fi first
#define se second
template<typename A, typename B> inline bool chmax(A &a, B b) { if (a<b) { a=b; return 1; } return 0; }
template<typename A, typename B> inline bool chmin(A &a, B b) { if (a>b) { a=b; return 1; } return 0; }
using ll = long long;
using pii = pair<int, int>;
constexpr ll INF = 1ll<<30;
constexpr ll longINF = 1ll<<60;
constexpr ll MOD = 1000000007;
constexpr bool debug = 0;
//---------------------------------//

struct LowestCommonAncestor {
public:
	LowestCommonAncestor(std::size_t _size) : _size(_size) {
		g.resize(_size);
		isbuilt = false;
	}
	LowestCommonAncestor(std::vector<std::vector<int> > g, int rootNode = 0, bool isper = true) : g(g) {
		_size = g.size();
		if (isper) build(rootNode);
	};
	
	void add_edge(int s, int t) {
		g[s].push_back(t);
	}
	
	void clear() {
		_size = 0;
		g.clear();
		par.clear();
		depth.clear();
		isbuilt = false;
	}
	
	void build(int rootNode = 0) {
		logsize = 1;
		while (1<<logsize < _size) ++logsize;
		depth.assign(_size, -1);
		par.assign(logsize, std::vector<int>(_size, -1));
		
		depth[rootNode] = 0;
		dfs(rootNode, -1);
		for (int i = 1; i < logsize; ++i) {
			for (int j = 0; j < _size; ++j) {
				if (~par[i - 1][j]) par[i][j] = par[i - 1][ par[i - 1][j] ];
			}
		}
		isbuilt = true;
	}
	
	int find(int a, int b) const {
		assert(isbuilt);
		if (depth[a] < depth[b]) std::swap(a, b);
		
		int up = depth[a] - depth[b];
		for (int i = 0; i < logsize; ++i) if (up >> i & 1) a = par[i][a];
		if (a == b) return a;
		for (int i = logsize - 1; i >= 0; i--) {
			if (par[i][a] != par[i][b]) {
				a = par[i][a];
				b = par[i][b];
			}
		}
		return par[0][a];
	}
	
	int query(int a, int b) const {
		assert(isbuilt);
		return depth[a] + depth[b] - 2 * depth[find(a, b)];
	}
	
private:
	std::size_t _size, logsize;
	std::vector<std::vector<int> > g, par;
	std::vector<int> depth;
	bool isbuilt;
	
	void dfs(int u, int p) {
		for (int v : g[u]) {
			if (v == p) continue;
			depth[v] = depth[u] + 1;
			par[0][v] = u;
			dfs(v, u);
		}
	}
};

int main() {
	int N, Q;
	cin >> N >> Q;
	vector<vector<int>> g(N), ginfo(N);
	vector<int> A(N - 1), B(N - 1), C(N - 1), D(N - 1);
	
	REP(i, N - 1) {
		scanf("%d %d %d %d", &A[i], &B[i], &C[i], &D[i]);
		--A[i]; --B[i]; --C[i];
		g[A[i]].emplace_back(B[i]);
		ginfo[A[i]].emplace_back(i);
		g[B[i]].emplace_back(A[i]);
		ginfo[B[i]].emplace_back(i);
	}
	
	vector<vector<int>> event(N), event2(N);
	LowestCommonAncestor lca(g);
	
	vector<int> X(Q), Y(Q), U(Q), V(Q);
	REP(i, Q) {
		scanf("%d %d %d %d", &X[i], &Y[i], &U[i], &V[i]);
		--X[i]; --U[i]; --V[i];
		
		event[U[i]].emplace_back(i);
		event[V[i]].emplace_back(i);
		event2[lca.find(U[i], V[i])].emplace_back(i);
	}
	
	int sum = 0;
	vector<int> colsum(N - 1), colcnt(N - 1), ans(Q);
	
	auto dfs = [&](auto &&dfs, int u, int par) -> void {
		
		for (int qi : event[u]) ans[qi] += sum - colsum[X[qi]] + colcnt[X[qi]] * Y[qi];
		
		REP(i, g[u].size()) {
			int v = g[u][i];
			if (v == par) continue;
			int ei = ginfo[u][i], ecol = C[ei];
			
			sum += D[ei];
			colsum[ecol] += D[ei];
			++colcnt[ecol];
			
			dfs(dfs, v, u);
			
			sum -= D[ei];
			colsum[ecol] -= D[ei];
			--colcnt[ecol];
		}
		
		for (int qi : event2[u]) ans[qi] -= 2 * (sum - colsum[X[qi]] + colcnt[X[qi]] * Y[qi]);
	};
	dfs(dfs, 0, -1);
	
	REP(i, Q) printf("%d\n", ans[i]);
	
	return 0;
}


Measured memory_bytes: 42448