#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

const int M = (1 << 18);
int st[M * 2];
long long int A[M * 2];


void UPDATE(int i, long long int val) {

	A[i] = val;
	int k = i + M - 1;
	st[k] = i;

	while (k > 0) {
		k = (k - 1) / 2;
		if (A[st[2 * k + 1]] <= A[st[2 * k + 2]]) { st[k] = st[2 * k + 1]; }
		else { st[k] = st[2 * k + 2]; }
	}
}

int RMQ(int a, int b, int K, int l, int r) {

	//cout << "K= " << K <<"  l= " <<l <<"  r= " <<r <<endl;

	if (b < l || r < a) { return 0; }

	if (a <= l && r <= b) { return st[K]; }

	int k1 = RMQ(a, b, 2 * K + 1, l, (l + r) / 2);
	int k2 = RMQ(a, b, 2 * K + 2, (l + r) / 2 + 1, r);

	if (A[k1] <= A[k2]) { return k1; }
	return k2;

}

int N, Q, a[100005], b[100005], c[100005], x[100005], u[100005], v[100005];
long long int d[100005], y[100005];

vector<int> Adj[100005], Edge_C[100005];
vector<long long int> Edge[100005];

int used[100005];

long long int dis[100005];

int vertex_color[100005];
long long int length[100005];

int parent[100005][20];
int depth[100005];

vector<int> COLOR[100005];
vector<int> COLOR_NUM[100005];
vector<long long int> COLOR_DIS[100005];

int id[100005];
int name[100005];

int last[250000];

int q;

void REC(int k, int d) {

	used[k] = 1;
	depth[k] = d;
	
	
	for (int m = 0; m < (int)Adj[k].size(); m++) {
		int y=Adj[k][m];
		if (used[y] == 0) {
			parent[y][0] = k;
			dis[y] = dis[k] + Edge[k][m];

			//========== pre
			last[y] = q;
			A[q] = depth[k] + 1; UPDATE(q, depth[k] + 1);
			COLOR[Edge_C[k][m]].push_back(q);
			int w = COLOR_DIS[Edge_C[k][m]].size();
			COLOR_DIS[Edge_C[k][m]].push_back(COLOR_DIS[Edge_C[k][m]][w - 1] + Edge[k][m]);
			w = COLOR_NUM[Edge_C[k][m]].size();
			COLOR_NUM[Edge_C[k][m]].push_back(COLOR_NUM[Edge_C[k][m]][w - 1] + 1);
			q++;
			//===========
			REC(y, d+1);

			//=========== post
			last[k] = q;
			A[q] = depth[k]; UPDATE(q, depth[k]);
			COLOR[Edge_C[k][m]].push_back(q);
			 w = COLOR_DIS[Edge_C[k][m]].size();
			COLOR_DIS[Edge_C[k][m]].push_back(COLOR_DIS[Edge_C[k][m]][w - 1] - Edge[k][m]);
			w = COLOR_NUM[Edge_C[k][m]].size();
			COLOR_NUM[Edge_C[k][m]].push_back(COLOR_NUM[Edge_C[k][m]][w - 1] -1);
			q++;
			//=============
		}
	}
}

int LCA(int m, int n) {

	if (depth[m] < depth[n]) {
		int tmp = m;
		m = n;
		n = tmp;
	}


	long long int dif = depth[m] - depth[n];
	for (int i = 17; i >= 0; i--) {
		if ((dif & ((long long int) 1 << i)) >0) {
			m = parent[m][i];
		}
	}

	//cout << "depth[m]= " << depth[m] << "  depth[n]= " << depth[n] << endl;

	if (m == n) { return m; }

	for (int k = 17; k >= 0; k--) {

		//cout << "k= " << k << " m= " << m << " n= " << n << " parent[m][k]= " <<parent[m][k]<< " parent[n][k]= " <<parent[n][k]<< endl;
		if  (parent[m][k] != parent[n][k]){
			m = parent[m][k];
			n = parent[n][k];
		}
		
	}

	return parent[m][0];
}

long long int CALC(int x, long long int y, int u, int v) {

	int w = LCA(u, v);

	//============================

	long long int dis1 = 0; int num1 = 0;

	int k1 = last[u];
	int k2 = last[w];

	//cout << "k1= " << k1 << "  k2= " << k2 << endl;

	if (k1 > k2) { int tmp = k2; k2 = k1; k1 = tmp; }

	int pos = RMQ(k1, k2, 0, 0, M - 1);
	//cout << "k1= " << k1 << "  k2= " << k2 << endl;
	//cout << "pos= " << pos << endl;

	int z1 = upper_bound(COLOR[x].begin(), COLOR[x].end(), k1)-COLOR[x].begin();
	z1--;
	int z2= upper_bound(COLOR[x].begin(), COLOR[x].end(), k2) - COLOR[x].begin();
	z2--;

	dis1 = abs(COLOR_DIS[x][z2] - COLOR_DIS[x][z1]);
	num1 = abs(COLOR_NUM[x][z2] - COLOR_NUM[x][z1]);

	
	//=============================

	long long int dis2 = 0; int num2 = 0;

	 k1 = last[v];
	 k2 = last[w];

	if (k1 > k2) { int tmp = k2; k2 = k1; k1 = tmp; }

	pos = RMQ(k1, k2, 0, 0, M - 1);

	//cout << "k1= " << k1 << "  k2= " << k2 << endl;
	//cout << "pos= " << pos << endl;

	 z1 = upper_bound(COLOR[x].begin(), COLOR[x].end(), k1) - COLOR[x].begin();
	z1--;
	z2 = upper_bound(COLOR[x].begin(), COLOR[x].end(), k2) - COLOR[x].begin();
	z2--;

	//cout << "z1= " << z1 << "  z2= " << z2 << endl;

	dis2 = abs(COLOR_DIS[x][z2] - COLOR_DIS[x][z1]);
	num2 = abs(COLOR_NUM[x][z2] - COLOR_NUM[x][z1]);



	//cout << "u= " << u << " v= " << v << " w= "<<w<<" id[m]= "<< id[m]<<" "<<" id[n]= " <<id[n]<< "  num1= " << num1 << "  num2= " << num2 << endl;

	//cout << "  dis1= " << dis1 << "  dis2= " << dis2 <<" num1= " <<num1<<" num2= " <<num2<< endl;
	return  y*(num1 + num2) - dis1 - dis2;

}



long long int INF = 1001001001001;


int main(void) {

	A[0] = INF;

	cin >> N >> Q;
	for (int i = 1; i <= N - 1; i++) {
		cin >> a[i] >> b[i] >> c[i] >> d[i];
		Adj[a[i]].push_back(b[i]);
		Adj[b[i]].push_back(a[i]);
		Edge[a[i]].push_back(d[i]);
		Edge[b[i]].push_back(d[i]);
		Edge_C[a[i]].push_back(c[i]);
		Edge_C[b[i]].push_back(c[i]);
	}

	for (int i = 1; i <= Q; i++) {
		cin >> x[i] >> y[i] >> u[i] >> v[i];
	}

	for (int i = 1; i <= N; i++) {
		COLOR[i].push_back(0);
		COLOR_DIS[i].push_back(0);
		COLOR_NUM[i].push_back(0);
	}

	
	q = 1;
	parent[1][0] = -1;
	A[1] = 1; UPDATE(1, 1);
	id[q] = 1;
	name[1] = q;
	q++;
	REC(1,1);
	
	/*for (int i = 1; i <= N; i++) {
		cout << "parent[" << i << "][0]= " << parent[i][0] << "  depth= " <<depth[i]<< endl;
	}*/

	for (int k = 0; k<=17; k++) {
		for (int i = 1; i <= N; i++) {
			if (parent[i][k] == -1) { parent[i][k + 1] = -1; }
			else {
				parent[i][k + 1] = parent[parent[i][k]][k];
			}
		}
	}

	/*for (int i = 1; i <= N; i++) {
		cout << "parent[" << i << "][2]= " << parent[i][2]  << endl;
	}*/

	/*for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			cout << "i= " << i << " j= " << j << "  LCA= " << LCA(i, j) << endl;
		}
	}*/

	
	/*for (int i = 1; i <= N - 1; i++) {
		cout << "color " << i << " : ";
		for (auto y : COLOR[i]) { cout << " " << y; }
		cout << endl;
	}*/
	

	/*for (int i = 0; i <= 10; i++) {
		cout<<" A[" << i << "]= " << A[i] << endl;
	}

	for (int i = 1; i <= 5; i++) {
		cout << "last[" << i << "]= " << last[i] << endl;
	}
	
	cout <<"RMQ= " << RMQ(4, 9, 0, 0, M - 1) << endl;
	*/

	for (int i = 1; i <= Q; i++) {
		int w = LCA(u[i], v[i]);

		long long int tmp = CALC(x[i], y[i], u[i], v[i]);

		cout<< dis[u[i]] + dis[v[i]] - dis[w] * 2 +tmp<< endl;
	}


	return 0;
}

Measured memory_bytes: 66276