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: Runtime Error)

#include <bits/stdc++.h>
 
using namespace std;
//#define int long long


 const int MAX = 1001;
const int MOD = 1000000007;

const int maxn =10000;
int n;
pair<int,int> dat[80000 ];
int id[maxn];
pair<int,int> matome[maxn][2*maxn+2];
vector<pair<int,pair<int,int>>> G[maxn];
  int n0=1;
void init(int N){
  
    while(n0<4*N-1)n0*=2;
    for(int i=0;i<n0;i++)dat[i]=make_pair(MOD,0);
    for(int i=0;i<N;i++)for(int j=0;j<2*N-1;j++)matome[i][j]=make_pair(0,0);
}
void update(int k, int a,int b){
    k+=n0-2;
    pair<int,int> t=make_pair(a,b);
    dat[k]=t;
    
    while(k>0){
        k=(k-1)/2;
        if(dat[k].first>a)dat[k]=t;
     //   cerr<<k<<endl;
    }
}
void add(int i,int x,int y,int iro){
    while(i<=n){
        matome[iro][i].first+=x;
        matome[iro][i].second+=y;
        i+= i& -i;
    }
}
int k=1;
void dfs(int v,int p, int d,int iro,int tyoku){
    id[v]=k;
  
    update(k,d,k);
    add(k,tyoku,1,iro);
    k++;
    for(int i=0;i<G[v].size();i++){
        if(G[v][i].first!=p){
            dfs(G[v][i].first,v,d+G[v][i].second.first,G[v][i].second.second, G[v][i].second.first);
        }
    }
    update(k,d-tyoku,k);
    add(k,-1*tyoku,-1,iro);
    k++;

}
pair<int,int> sum(int iro,int i){
    pair<int,int> s=make_pair(0,0);
    while(i>0){
        s.first+=matome[iro][i].first;
        s.second+=matome[iro][i].second;
        i-=i&-i;
    }
    return s;
}
pair<int,int> query(int a,int b,int K,int l,int r){
    if(r<=a || b<=l) return make_pair(MOD,-1);
    if(a<=l&&r<=b){
       // cerr<<K<<'u'<<endl;
        return dat[K];
    }

    else{
        pair<int,int> vl=query(a,b,K*2+1,l,(l+r)/2),vr=query(a,b,K*2+2,(l+r)/2,r);
        if(vl.first<vr.first)return vl;
        else  return vr;
    }
}
signed main(){
   int q;
   cin>>n>>q;
   int a,b,c,d;
   for(int i=0;i<n-1;i++){
       cin>>a>>b>>c>>d;
       G[a-1].push_back(make_pair(b-1,make_pair(d,c-1)));
       G[b-1].push_back(make_pair(a-1,make_pair(d,c-1)));
   }
   init(n);
    dfs(0,-1,0,n,0);
   //for(int i=0;i<n;i++)cerr<<id[i];
    int x,y,u,v; pair<int, int> que;
   // for(int i=3;i<=8;i++)cerr<<dat[i+n0-2].first<<' ';
    for(int i=0;i<q;i++){
        cin>>x>>y>>u>>v;
       que=query(min(id[u-1],id[v-1]),max(id[u-1],id[v-1])+1,0,1,n0+1);
      //  cerr<<dat[id[u-1]+n0-2].first<<' '<<dat[id[v-1]+n0-2].first<<' '<<que.first<<endl;
       // cerr<<que.second<<' ';
      //  cerr<<sum(x-1,id[u-1]).first+sum(x-1,id[v-1]).first-2*sum(x-1,que.second).first<<' '<<sum(x-1,id[u-1]).second+sum(x-1,id[v-1]).second-2*sum(x-1,que.second).second<<endl;
        cout<<dat[id[u-1]+n0-2].first+dat[id[v-1]+n0-2].first-2*que.first-(sum(x-1,id[u-1]).first+sum(x-1,id[v-1]).first-2*sum(x-1,que.second).first)+y*(sum(x-1,id[u-1]).second+sum(x-1,id[v-1]).second-2*sum(x-1,que.second).second)<<endl;
      //  cerr<<endl;
    }

   return 0;
}