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 (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <stdio.h>

typedef struct List {
	struct List *next;
	int v, col, len;
} list;

void DFS(int u, list* adj[], list* memo[], int dep[], int count[], int sum[])
{
	list *p;
	for (p = memo[u]; p != NULL; p = p->next) p->len = sum[0] - sum[p->col] + p->len * count[p->col];
	for (p = adj[u]; p != NULL; p = p->next) {
		if (dep[p->v] < dep[u]) continue;
		count[p->col]++;
		sum[0] += p->len;
		sum[p->col] += p->len;
		DFS(p->v, adj, memo, dep, count, sum);
		count[p->col]--;
		sum[0] -= p->len;
		sum[p->col] -= p->len;
	}
}

int main()
{
	int i, N, Q, u, w, c, l;
	list *adj[100001] = {}, e[200001], *p;
	scanf("%d %d", &N, &Q);
	for (i = 0; i < N - 1; i++) {
		scanf("%d %d %d %d", &u, &w, &c, &l);
		e[i*2].v = w;
		e[i*2+1].v = u;
		e[i*2].col = c;
		e[i*2+1].col = c;
		e[i*2].len = l;
		e[i*2+1].len = l;
		e[i*2].next = adj[u];
		e[i*2+1].next = adj[w];
		adj[u] = &(e[i*2]);
		adj[w] = &(e[i*2+1]);
	}
	
	int dep[100001] = {}, anc[100001][20] = {}, q[100001], head, tail;
	dep[1] = 1;
	q[0] = 1;
	for (head = 0, tail = 1; head < tail; head++) {
		u = q[head];
		for (p = adj[u]; p != NULL; p = p->next) {
			if (dep[p->v] == 0) {
				dep[p->v] = dep[u] + 1;
				q[tail++] = p->v;
				for (i = 0, w = u, anc[p->v][0] = u; anc[w][i] != 0; w = anc[w][i++]) anc[p->v][i+1] = anc[w][i];
			}
		}
	}
	
	int x[100001], y[100001], s[100001], t[100001], lca[100001];
	list *memo[100001] = {}, d[300001];
	for (i = 1; i <= Q; i++) scanf("%d %d %d %d", &(x[i]), &(y[i]), &(s[i]), &(t[i]));
	for (i = Q; i >= 1; i--) {
		d[i*3-1].v = s[i];
		d[i*3-1].col = x[i];
		d[i*3-1].len = y[i];
		d[i*3-1].next = memo[s[i]];
		memo[s[i]] = &(d[i*3-1]);
		d[i*3-2].v = t[i];
		d[i*3-2].col = x[i];
		d[i*3-2].len = y[i];
		d[i*3-2].next = memo[t[i]];
		memo[t[i]] = &(d[i*3-2]);
		
		u = s[i];
		w = t[i];
		while (dep[u] > dep[w]) {
			for (l = 0; dep[anc[u][l+1]] >= dep[w]; l++);
			u = anc[u][l];
		}
		while (dep[w] > dep[u]) {
			for (l = 0; dep[anc[w][l+1]] >= dep[u]; l++);
			w = anc[w][l];
		}
		while (u != w) {
			for (l = 0; anc[u][l+1] != anc[w][l+1]; l++);
			u = anc[u][l];
			w = anc[w][l];
		}
		lca[i] = u;
		d[i*3].v = u;
		d[i*3].col = x[i];
		d[i*3].len = y[i];
		d[i*3].next = memo[u];
		memo[u] = &(d[i*3]);
	}
	
	int count[100001] = {}, sum[100001] = {};
	DFS(1, adj, memo, dep, count, sum);
	
	for (i = 1; i <= Q; i++) {
		printf("%d\n", memo[s[i]]->len + memo[t[i]]->len - memo[lca[i]]->len);
		memo[s[i]] = memo[s[i]]->next;
		memo[t[i]] = memo[t[i]]->next;
		memo[lca[i]] = memo[lca[i]]->next;
	}
	fflush(stdout);
	return 0;
}