#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
template<class T> ostream& operator<<(ostream &os, vector<T> V) {
os << "[ "; for(auto v : V) os << v << " "; return os << "]";}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {
    return os << "(" << P.first << "," << P.second << ")";}

// #define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...) 1
#endif
typedef long long ll;
typedef double ld;
#define pll pair<ll,ll>
#define pii pair<int, int>
#define pb push_back
#define mp(x, y) make_pair((x), (y))
#define F first
#define S second
#define I insert
#define vi vector<int>
#define vll vector<ll>
#define vpll vector<pll>
#define all(x) (x).begin(), (x).end()
#define sz(x) (ll)(x).size()
   
const ll Mod = 1e9 + 7;
const int N = 101111;
const int LN = 20;
ll n ,  u , v , c , d , par[N][LN] , depth[N] , Dp[N] ,   q ;
vector< pair<ll,pll> >  G[N];




struct node{
    ll val , no;
    node *left , *right;
    node() {}
    node(node *l , node *r , ll v , ll n){
        left = l;
        right = r;
        val = v;
        no  = n;
    }
};

node *version[N];
void build(node *n , int low , int high){
    if(low == high){
        n->val = 0;
        n->no  = 0;
        return;
    }
    int mid = (low+high)/2;
    n->left = new node(NULL , NULL , 0 , 0);
    n->right = new node(NULL , NULL , 0 , 0);
    build(n->left , low , mid);
    build(n->right , mid+1 , high);
    n->val = 0;
    n->no  = 0;
}

void upgrade(node *prev , node *curr , int low , int high , int idx , int value){
    
    if(low > idx || idx > high)
        return;
    if(low == high){ 
        
        curr->val = prev->val + value;
        curr->no  = prev->no + 1;
        return;
    }
    
    int mid = (low+high)/2;
    if(idx <= mid){
        
        curr->right = prev->right;
        
        curr->left = new node(NULL , NULL , 0 , 0);
        upgrade(prev->left , curr->left , low , mid , idx , value);
    }
    else
    {
        
        curr->left = prev->left;
        
        curr->right = new node(NULL , NULL , 0 , 0);
        upgrade(prev->right , curr->right , mid+1 , high , idx , value);
    }    
}

void dfs(int s, int p){
    par[s][0] = p;
    Dp[s] = Dp[p] + 1;
    
    

    for(auto it : G[s]){
        if(it.F != p){
            upgrade(version[s] , version[it.F] ,1 , n-1 , it.S.F , it.S.S);
            depth[it.F] = depth[s] + it.S.S;
            dfs(it.F , s);
        }
    }
    
}
int LCA(int u , int v){
    if(Dp[u] < Dp[v]) 
        swap(u , v);
    
    int diff = Dp[u] - Dp[v];
    for(int i = 0 ;i < LN ; i++)
        if(diff&(1<<i))
            u = par[u][i];
    if(u != v){
        for(int i = LN-1 ;i >= 0; i--){
            if(par[u][i] != par[v][i]){
                u = par[u][i];
                v = par[v][i];
            }
        }
        u = par[u][0];
    }
    return u;
}

node* query(node *i , int idx , int low , int high){
    
    if(low ==  high){
        return i;
    }
    int mid = (low + high)/2;
    
    if(idx <= mid)
        return query(i->left, idx , low , mid );
    else
        return query(i->right ,idx ,  mid+1 , high);
}

int main(){
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); 
    cin >> n >> q;

    for(int i = 0 ;i < n-1 ; i++){
        cin >> u >> v >> c >> d;
        G[u].pb(mp(v , mp(c , d)));
        G[v].pb(mp(u ,mp(c , d)));
    }

    
    for(int i = 1 ;i <= n ;i++)
        version[i] = new node(NULL , NULL , 0 , 0);
    build(version[1] , 1 , n-1);
    
    
    depth[1] = 0;
    Dp[0] = -1;
    memset(par , -1 , sizeof(par));
    dfs(1 , 0);

    for(int i = 0 ;i < LN-1 ; i++){
        for(int j = 1 ; j <= n ; j++){
            if(par[j][i] != -1)
                par[j][i+1] = par[par[j][i]][i]; 
        }   
    }
    
    while(q--){
        ll x ,y , u , v;
        cin >> x >> y >> u >> v;
        ll lca = LCA(u , v);
        if(lca == 0 || lca == -1)
            lca = 1;
        
        ll ans = depth[u] + depth[v] - 2*depth[lca];
        node  *a = query(version[u] , x , 1 , n-1) ;
        node *b = query(version[v] , x , 1 , n-1);

        node *c = query(version[lca] , x , 1 , n-1);
        
        
        cout << ans - (a->val + b->val - 2*(c->val)) + y*(a->no + b->no - 2*(c->no)) << '\n';
    }


    return 0;
}

/*
45 44
low  : 1 |  high  : 100 |  count  : 23 |  mid : 50
low  : 51 |  high  : 100 |  count  : 15 |  mid : 75ZN
low  : 76 |  high  : 100 |  count  : 10 |  mid : 88
low  : 89 |  high  : 100 |  count  : 4 |  mid : 94
low  : 95 |  high  : 100 |  count  : 3 |  mid : 97
low  : 98 |  high  : 100 |  count  : 1 |  mid : 99
980769055
0
 */

Measured memory_bytes: 129920