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 <algorithm>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

typedef long long ll;

#define sz size()
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(c) (c).begin(), (c).end()
#define rep(i,a,b) for(ll i=(a);i<(b);++i)
#define per(i,a,b) for(ll i=b-1LL;i>=(a);--i)
#define clr(a, b) memset((a), (b) ,sizeof(a))
#define ctos(c) string(1,c)
#define print(x) cout<<#x<<" = "<<x<<endl;

#define MOD 1000000007

#define MAX_V 200100
#define MAX_LOG_V 17

vector<int> G[MAX_V];
int root;

int parent[MAX_LOG_V][MAX_V];
int depth[MAX_V];

void ae(int from, int to){
  G[from].push_back(to);
  G[to].push_back(from);
}

void dfsl(int v, int p, int d){
  parent[0][v] = p;
  depth[v] = d;
  for(int i = 0; i < G[v].size(); i++){
    if(G[v][i] != p)dfsl(G[v][i],v,d+1);
  }
}

void init(int V){
  dfsl(root,-1,0);
  for(int k = 0; k+1 < MAX_LOG_V; k++){
    for(int v = 0; v < V; v++){
      if(parent[k][v] < 0)parent[k+1][v]=-1;
      else parent[k+1][v] = parent[k][parent[k][v]];
    }
  }
}

int lca(int u, int v){
  if(depth[u] > depth[v])swap(u,v);
  for(int k = 0; k < MAX_LOG_V; k++){
    if((depth[v] - depth[u]) >> k & 1){
      v = parent[k][v];
    }
  }
  if(u == v)return u;
  for(int k = MAX_LOG_V - 1; k >= 0; k--){
    if(parent[k][u] != parent[k][v]){
      u = parent[k][u];
      v = parent[k][v];
    }
  }
  return parent[0][u];
}

vector<vector<pair<ll,pair<ll,ll> > > > vv;

ll d1[200100];
ll d2[200100];
ll d3[200100];

vector<vector<pair<ll,pair<ll,ll> > > > v1;

void dfs(ll a, ll p, ll h){
  d1[a] = h;
  rep(i,0,v1[a].sz){
  	ll b = v1[a][i].fi;
  	v1[a][i].se.fi = d2[b];
  	v1[a][i].se.se = d3[b];
  }
  if(vv[a].sz==1&&p!=-1){
    return;
  }
  rep(i,0,vv[a].sz){
    if(vv[a][i].fi==p)continue;
    ll c = vv[a][i].se.fi;
    ll d = vv[a][i].se.se;
    d2[c]++;
    d3[c]+=d;
    dfs(vv[a][i].fi,a,h+d);
    d2[c]--;
    d3[c]-=d;
  }
  return;
}

void dfs2(ll a, ll p, ll h){
  if(vv[a].sz==1&&p!=-1){
    return;
  }
  rep(i,0,vv[a].sz){
    if(vv[a][i].fi==p)continue;
    ae(a,vv[a][i].fi);
    dfs2(vv[a][i].fi,a,h+1);
  }
  return;
}

int main() {
	clr(d1,0);
	clr(d2,0);
	clr(d3,0);
	ll n,q;
	cin>>n>>q;
	vector<vector<pair<ll,pair<ll,ll> > > > vv_(n,vector<pair<ll,pair<ll,ll> > >());
	vv = vv_;
	rep(i,0,n-1){
		ll a,b,c,d;
		cin>>a>>b>>c>>d;
		a--;b--;
		vv[a].pb(mp(b,mp(c,d)));
		vv[b].pb(mp(a,mp(c,d)));
	}
	root = 0;
	init(100100);
	dfs2(0,-1,0);
	vector<pair<pair<ll,ll>,pair<ll,ll> > > vq;
	vector<vector<pair<ll,pair<ll,ll> > > > v1_(n,vector<pair<ll,pair<ll,ll> > >());
	v1 = v1_;
	rep(i,0,q){
		ll a,b,c,d;
		cin>>a>>b>>c>>d;
		c--;d--;
		vq.pb(mp(mp(a,b),mp(c,d)));
		ll e = lca(c,d);
		v1[c].pb(mp(a,mp(0,0)));
		v1[d].pb(mp(a,mp(0,0)));
		v1[e].pb(mp(a,mp(0,0)));
	}
	dfs(0,-1,0);
	map<pair<ll,ll>,ll> ma1,ma2;
	rep(i,0,v1.sz){
		rep(j,0,v1[i].sz){
			ma1[mp(i,v1[i][j].fi)]=v1[i][j].se.fi;
			ma2[mp(i,v1[i][j].fi)]=v1[i][j].se.se;
		}
	}
	rep(i,0,vq.sz){
		ll a = vq[i].fi.fi;
		ll b = vq[i].fi.se;
		ll c = vq[i].se.fi;
		ll d = vq[i].se.se;
		ll e = lca(c,d);
		ll dd = d1[c]+d1[d]-d1[e]*2;
		ll ee1 = ma1[mp(c,a)]+ma1[mp(d,a)]-ma1[mp(e,a)]*2;
		ll ee2 = ma2[mp(c,a)]+ma2[mp(d,a)]-ma2[mp(e,a)]*2;
		cout << dd-ee2+ee1*b << endl;
	}
	return 0;
}