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<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define mkp make_pair
#define fi first
#define se second
void read(int &x){
	register char ch=getchar();x=0;
	for(;ch<'0'||ch>'9';ch=getchar());
	for(;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
}
void write(int x){
	if(x>9)write(x/10);
	putchar(x%10+'0');
}
struct gra{
	int to,col,val;
};
struct query{
	int v,val;
};
struct ask{
	int u,v,val,id;
};
int n,m,siz[100004],p[100004],h[100004],nxt[100004];
vector<gra>g[100004];
vector<query>q[100004];
void dfs1(int x,int par){
	siz[x]=1,p[x]=par;
	int maxx=0;
	for(int i=0;i<g[x].size();i++)if(g[x][i].to!=par){
		nxt[g[x][i].to]=g[x][i].val;
		q[g[x][i].col].push_back((query){g[x][i].to,g[x][i].val});
		dfs1(g[x][i].to,x),siz[x]+=siz[g[x][i].to];
		if(maxx<siz[g[x][i].to])maxx=siz[g[x][i].to],h[x]=g[x][i].to;
	}
}
int cnt,cmp[100004],pre[100004];
void dfs2(int x,int par,int H){
	cmp[x]=++cnt,pre[cnt]=nxt[x],nxt[x]=H;
	if(h[x])dfs2(h[x],x,H);
	for(int i=0;i<g[x].size();i++)if(g[x][i].to!=h[x]&&g[x][i].to!=par)
		dfs2(g[x][i].to,x,g[x][i].to);
}
void init(){
	for(int i=2;i<=n;i++)pre[i]+=pre[i-1];
}
int isans(int l,int r,int x){
	return cmp[l]<=x&&x<=cmp[r];
}
int ans[100004];
void lca_ans_sp(int u,int v,int id){
	while(1){
		if(cmp[u]>cmp[v])swap(u,v);
		int L=nxt[v];
		if(isans(L,v,u)){
			ans[id]+=pre[cmp[v]]-pre[cmp[u]];
			return;
		}
		ans[id]+=pre[cmp[v]]-pre[cmp[L]-1];
		v=p[L];
	}
}
vector<ask>a[100004];
int bit1[100004],bit2[100004];
void add(int id,int a1,int a2){
	while(id<=n){
		bit1[id]+=a1,bit2[id]+=a2;
		id+=(id&-id);
	}
}
pii got(int id){
	pii ret=mkp(0,0);
	while(id){
		ret.fi+=bit1[id],ret.se+=bit2[id];
		id-=(id&-id);
	}
	return ret;
}
pii qry(int l,int r){
	pii A=got(l-1),B=got(r);
	return mkp(B.fi-A.fi,B.se-A.se);
}
pii fans(int u,int v){
	pii ret=mkp(0,0);
	while(1){
		if(cmp[u]>cmp[v])swap(u,v);
		int L=nxt[v];
		if(isans(L,v,u)){
			pii gt=qry(cmp[u]+1,cmp[v]);
			ret.fi+=gt.fi,ret.se+=gt.se;
			return ret;
		}
		pii gt=qry(cmp[L],cmp[v]);
		ret.fi+=gt.fi,ret.se+=gt.se;
		v=p[L];
	}
}
int main(){
	read(n),read(m);
	for(int i=1;i<n;i++){
		int A,B,C,D;read(A),read(B),read(C),read(D);
		g[A].push_back((gra){B,C,D});
		g[B].push_back((gra){A,C,D});
	}
	dfs1(1,-1);
	dfs2(1,-1,1);
	return 0;
	init();
	if(n==100000)return 0;
	for(int i=1;i<=m;i++){
		int C,D,A,B;read(C),read(D),read(A),read(B);
		lca_ans_sp(A,B,i);
		a[C].push_back((ask){A,B,D,i});
	}
	if(n==100000)return 0;
	for(int i=1;i<n;i++)if(!a[i].empty()){
		for(int j=0;j<q[i].size();j++)add(cmp[q[i][j].v],q[i][j].val,1);
		for(int j=0;j<a[i].size();j++){
			pii ret=fans(a[i][j].u,a[i][j].v);
			ans[a[i][j].id]-=ret.fi;
			ans[a[i][j].id]+=ret.se*a[i][j].val;
		}
		for(int j=0;j<q[i].size();j++)add(cmp[q[i][j].v],-q[i][j].val,-1);
	}
	for(int i=1;i<=m;i++)write(ans[i]),puts("");
}