Problem: 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.

Example

Input

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


Output

130
200
60

Solution (in CPP):

Solution:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#define popcount __builtin_popcount
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
int n;
vector<P> g[100000];
int d[100000];
int p[17][100000];
bool used[100000];
void dfs0(int x){
	used[x]=1;
	for(auto pr:g[x]){
        int y=pr.first;
		if(!used[y]){
			d[y]=d[x]+1;
			p[0][y]=x;
			dfs0(y);
		}
	}
}
void init_lca(){
    dfs0(0);
	for(int i=1; i<17; i++){
        for(int x=0; x<n; x++){
            p[i][x]=p[i-1][p[i-1][x]];
        }
    }
}
int lca(int a, int b){
    if(d[a]>d[b]) swap(a, b);
    int a1=a, b1=b;
    int dd=d[b]-d[a], i=0;
    while(dd>0){
        if(dd%2==1){
            b1=p[i][b1];
        }
        dd/=2;
        i++;
    }
    if(a1==b1) return a1;
    for(int i=16; i>=0; i--){
        if(p[i][a1]!=p[i][b1]){
            a1=p[i][a1], b1=p[i][b1];
        }
    }
    return p[0][a1];
}
vector<int> v[100010];
vector<int> vm[100010];
int c[100010]; ll dist[100010];
int cx[100010]; ll y[100010];
ll cnt[100010], dc[100010], ds;
ll ans[100010];
void dfs(int x){
    used[x]=1;
    for(auto i:v[x]){
        ans[i]+=(ds-dc[cx[i]]+cnt[cx[i]]*y[i]);
    }
    for(auto i:vm[x]){
        ans[i]-=2*(ds-dc[cx[i]]+cnt[cx[i]]*y[i]);
    }
    for(auto pr:g[x]){
        int y=pr.first;
        if(used[y]) continue;
        int i=pr.second;
        cnt[c[i]]++;
        dc[c[i]]+=dist[i];
        ds+=dist[i];
        dfs(y);
        cnt[c[i]]--;
        dc[c[i]]-=dist[i];
        ds-=dist[i];
    }
}
int main()
{
    int q;
    cin>>n>>q;
    for(int i=0; i<n-1; i++){
      int a, b;
        cin>>a>>b>>c[i]>>dist[i];
        a--; b--;
        g[a].push_back({b, i});
        g[b].push_back({a, i});
    }
    init_lca();
    for(int i=0; i<q; i++){
        int ui, vi; cin>>cx[i]>>y[i]>>ui>>vi;
        ui--; vi--;
        v[ui].push_back(i);
        v[vi].push_back(i);
        vm[lca(ui, vi)].push_back(i);
    }
    fill(used, used+n, 0);
    dfs(0);
    for(int i=0; i<q; i++) cout<<ans[i]<<endl;
    return 0;
}