Problem:
Score : 600 points

Problem Statement

There is a tree with N vertices numbered 1 to N.
The i-th edge in this tree connects Vertex a_i and Vertex b_i, and the color and length of that edge are c_i and d_i, respectively.
Here the color of each edge is represented by an integer between 1 and N-1 (inclusive). The same integer corresponds to the same color, and different integers correspond to different colors.

Answer the following Q queries:

Query j (1 \leq j \leq Q): assuming that the length of every edge whose color is x_j is changed to y_j, find the distance between Vertex u_j and Vertex v_j. (The changes of the lengths of edges do not affect the subsequent queries.)

Constraints

2 \leq N \leq 10^5

1 \leq Q \leq 10^5

1 \leq a_i, b_i \leq N

1 \leq c_i \leq N-1

1 \leq d_i \leq 10^4

1 \leq x_j \leq N-1

1 \leq y_j \leq 10^4

1 \leq u_j < v_j \leq N

The given graph is a tree.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N Q
a_1 b_1 c_1 d_1
:
a_{N-1} b_{N-1} c_{N-1} d_{N-1}
x_1 y_1 u_1 v_1
:
x_Q y_Q u_Q v_Q

Output

Print Q lines. The j-th line (1 \leq j \leq Q) should contain the answer to Query j.

Sample Input 1

5 3
1 2 1 10
1 3 2 20
2 4 4 30
5 2 1 40
1 100 1 4
1 100 1 5
3 1000 3 4

Sample Output 1

130
200
60

The graph in this input is as follows:

Here the edges of Color 1 are shown as solid red lines, the edge of Color 2 is shown as a bold green line, and the edge of Color 4 is shown as a blue dashed line.

Query 1: Assuming that the length of every edge whose color is 1 is changed to 100, the distance between Vertex 1 and Vertex 4 is 100 + 30 = 130.

Query 2: Assuming that the length of every edge whose color is 1 is changed to 100, the distance between Vertex 1 and Vertex 5 is 100 + 100 = 200.

Query 3: Assuming that the length of every edge whose color is 3 is changed to 1000 (there is no such edge), the distance between Vertex 3 and Vertex 4 is 20 + 10 + 30 = 60. Note that the edges of Color 1 now have their original lengths.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

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

using namespace std;

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

vector<int> Adj[100005], Edge[100005], Edge_C[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<long long int> COLOR_DIS[100005];

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

int q;

void REC(int k, int d) {

	used[k] = 1;
	depth[k] = d;


	int sign = 1;
	for (int m = 0; m < (int)Adj[k].size(); m++) {
		int y=Adj[k][m];
		if (used[y] == 0) {
			parent[y][0] = k;
			id[y] = q;
			name[q] = y;
			q++;
			dis[y] = dis[k] + Edge[k][m];
			vertex_color[y] = Edge_C[k][m];
			length[y] = Edge[k][m];

			COLOR[Edge_C[k][m]].push_back(id[y]);
			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] + length[y]);
			REC(y, d+1);
		}
	}
}

int LCA(int m, int n) {

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


	int dif = depth[m] - depth[n];
	for (int i = 17; i >= 0; i--) {
		if ((dif & (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 << 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 m = u;
	if (w != u) {
		int dif = depth[m] - depth[w]-1;
		for (int i = 17; i >= 0; i--) {
			if (dif & (1 << i)) { m = parent[m][i]; }
		}

		int  pos_u = upper_bound(COLOR[x].begin(), COLOR[x].end(), id[u])-COLOR[x].begin();
		pos_u--;

		int pos_m= upper_bound(COLOR[x].begin(), COLOR[x].end(), id[m]) - COLOR[x].begin();
		pos_m--;

		num1 += pos_u - pos_m;
		dis1 += COLOR_DIS[x][pos_u] - COLOR_DIS[x][pos_m];
		if (vertex_color[m] == x) { num1++; dis1 += length[m]; }

	}

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

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

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

		int  pos_v = upper_bound(COLOR[x].begin(), COLOR[x].end(), id[v]) - COLOR[x].begin();
		pos_v--;

		int pos_n = upper_bound(COLOR[x].begin(), COLOR[x].end(), id[n]) - COLOR[x].begin();
		pos_n--;

		num2 += pos_v - pos_n;
		dis2 += COLOR_DIS[x][pos_v] - COLOR_DIS[x][pos_n];
		if (vertex_color[n] == x) { num2++; dis2 += length[n]; }

	}

	return  y*(num1 + num2) - dis1 - dis2;

}


int main(void) {


	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);
	}

	
	q = 1;
	parent[1][0] = -1;
	id[q] = 1;
	name[1] = 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++) {
			parent[i][k + 1] = parent[parent[i][k]][k];
		}
	}

	/*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 <= 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;
}