#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
const int mod=1000000007,MAX=1<<19;
const ll INF=1LL<<40;
struct edge{
    int to;
    int color;
    ll dis;
};

vector<edge> G[MAX];
int n;
ll fi[MAX],la[MAX],bit[MAX+1],vs[MAX],depth[MAX];
vector<pair<ll,ll>> D[MAX],Dsum[MAX];

ll sum(ll i){
    int s=0;
    while(i>0){
        s+=bit[i];
        i-=i&-i;
    }
    return s;
}

//sからtの和=sum(t)-sum(s-1)

void add(int i,ll x){
    while(i<=n){
        bit[i]+=x;
        i+=i&-i;
    }
}

void DFS(int v,int p,int d,int &k){
    fi[v]=k;
    la[v]=k;
    vs[k+n-1]=v;
    depth[k+n-1]=d;
    k++;
    
    for(int i=0;i<G[v].size();i++){
        edge E=G[v][i];
        if(E.to!=p){
            add(k-1,E.dis);
            D[E.color].push_back({k-1,E.dis});
            
            DFS(G[v][i].to,v,d+1,k);
            
            add(k-1,-E.dis);
            D[E.color].push_back({k-1,-E.dis});
            
            la[v]=k;
            vs[k+n-1]=v;
            depth[k+n-1]=d;
            k++;
        }
    }
}

void rmq_init(){
    for(int i=n-2;i>=0;i--){
        if(depth[i*2+1]<depth[i*2+2]){
            depth[i]=depth[i*2+1];
            vs[i]=vs[i*2+1];
        }else{
            depth[i]=depth[i*2+2];
            vs[i]=vs[i*2+2];
        }
    }
}

void init(int n_){
    n=1;
    while(n<n_) n*=2;
    int k=1;
    DFS(0,-1,0,k);
    rmq_init();
}

int query(ll a,ll b,int k,int l,int r){
    
    if(r<=a||b<=l) return -1;
    if(a<=l&&r<=b) return k;
    else{
        int vl=query(a,b,2*k+1,l,(l+r)/2);
        int vr=query(a,b,2*k+2,(l+r)/2,r);
        if(vl==-1) return vr;
        if(vr==-1) return vl;
        if(depth[vl]<depth[vr]) return vl;
        return vr;
    }
}

ll lca(int u,int v){
    ll a=min(fi[u],fi[v]),b=max(fi[u],fi[v]);
    return vs[query(a,b+1,0,0,n)];
}

int main(){
    
    int N,Q;cin>>N>>Q;
    
    for(int i=0;i<N-1;i++){
        int a,b,c;
        ll d;cin>>a>>b>>c>>d;
        a--;b--;
        c--;
        G[a].push_back({b,c,d});
        G[b].push_back({a,c,d});
    }
    init(2*N+1);
    
    for(int i=0;i<N;i++){
        Dsum[i].push_back({0,0});
        if(D[i].size()==0) continue;
        Dsum[i].push_back({D[i][0].second,1});
        
        for(int j=1;j<D[i].size();j++){
            pair<ll,ll> p;
            p.first=Dsum[i][j].first+D[i][j].second;
            if(D[i][j].second>0) p.second=Dsum[i][j].second+1;
            else p.second=Dsum[i][j].second-1;
            Dsum[i].push_back(p);
        }
    }
    
    while(Q){
        int x,y,a,b;cin>>x>>y>>a>>b;
        x--;a--;b--;
        ll ans=sum(fi[a]-1)+sum(fi[b]-1)-2*sum(fi[lca(a,b)]-1);
        
        ll s=lower_bound(all(D[x]),make_pair(fi[a]-1,INF))-D[x].begin();
        ll t=lower_bound(all(D[x]),make_pair(fi[b]-1,INF))-D[x].begin();
        ll u=lower_bound(all(D[x]),make_pair(fi[lca(a,b)]-1,INF))-D[x].begin();
        
        //cout<<s<<" "<<t<<" "<<u<<" "<<ans<<endl;
        
        ll d=Dsum[x][s].first+Dsum[x][t].first-2*Dsum[x][u].first;
        ll cnt=Dsum[x][s].second+Dsum[x][t].second-2*Dsum[x][u].second;
        
        //cout<<d<<" "<<cnt<<endl;
        
        ans-=d;
        ans+=cnt*y;
        
        cout<<ans<<endl;
        
        Q--;
    }
    
    
}

//sum(fi[a]-1)+sum(fi[b]-1)-2*sum(fi[lca(a,b)]-1)が長さ変更前の長さ



Measured memory_bytes: 79468