#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define F first
#define S second
#define int long long
#define ll long long
//#define int  unsigned long long
#define pb push_back
//#define double long double

using namespace std;
using namespace __gnu_pbds;
typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
const int mod = 1e9 + 7;
const int N = 120000;
const int K = 350;
int bad[N], used[N], d1[500][N], d2[500][N], p[23][N], tin[N], tout[N], n, cnt, rev[N], timer;
vector < pair < int, pair < int, int > > > a[N], g[N];
void calc(int x){
    for (int i = 1; i <= n; i++) used[i] = 0;
    queue < int > q;
    q.push(1);
    used[1] = 1;
    p[0][1] = 1;
    while(!q.empty()){
        int v = q.front();
        q.pop();
        for (auto u: g[v]){
            if (used[u.F]) continue;
            if (x == 0) p[0][u.F] = v;
            if (u.S.F == x || x == 0){
                d1[cnt][u.F] = d1[cnt][v] + 1;
                d2[cnt][u.F] = d2[cnt][v] + u.S.S;
            } else{
                d1[cnt][u.F] = d1[cnt][v];
                d2[cnt][u.F] = d2[cnt][v];
            }
            used[u.F] = 1;
            q.push(u.F);
        }
    }
    cnt++;
}
int lca(int u, int v){
    if (d1[0][u] > d1[0][v]) swap(u, v);
    int d = d1[0][v] - d1[0][u];
    for (int i = 18; i >= 0; i--){
        if (d & (1 << i)){
            v = p[i][v];
        }
    }
    if (u == v) return u;
    for (int i = 18; i >= 0; i--){
        if (p[i][v] != p[i][u]){
            u = p[i][u];
            v = p[i][v];
        }
    }
    return p[0][v];
}
void dfs(int v, int p = -1){
    timer++;
    tin[v] = timer;
    for (auto u: g[v]){
        if (u.F != p) dfs(u.F, v);
    }
    timer++;
    tout[v] = timer;
}
bool anc(int v, int u){
    if (tin[u] <= tin[v] && tout[u] >= tout[v]) return 1;
    return 0;
}
main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    //freopen("input.txt", "r", stdin);
    int q;
    cin >> n >> q;
    for (int i = 1; i < n; i++){
        int u, v, c, d;
        cin >> u >> v >> c >> d;
        a[c].pb({d, {u, v}});
        g[u].pb({v, {c, d}});
        g[v].pb({u, {c, d}});
    }
    calc(0);
    dfs(1);
    for (int i = 1; i < n; i++){
        if (a[i].size() > K){
            bad[i] = 1;
            rev[i] = cnt;
            calc(i);
        }
    }
    for (int i = 1; i < 19; i++){
        for (int j = 1; j <= n; j++){
            p[i][j] = p[i - 1][p[i - 1][j]];
        }
    }
    while(q--){
        int u, v, x, y;
        cin >> x >> y >> u >> v;
        int k = lca(u, v);
        int res = d2[0][v] + d2[0][u] - 2 * d2[0][k];
        if (bad[x]){
            x = rev[x];
           // cout << res << " -- " << " " << d2[x][v] << " " << d2[x][u] << " " << x << " " << d2[x][k] << endl;
            res = res - (d2[x][v] + d2[x][u] - 2 * d2[x][k]);
            res = res + y * (d1[x][v] + d1[x][u] - 2 * d1[x][k]);
            cout << res << endl;
        } else{
            for (auto j: a[x]){
                int u1 = j.S.F;
                int v1 = j.S.S;
                if ((anc(u, u1) && anc(u, v1)) && (anc(v1, k) && anc(u1, k))){
                    res -= j.F;
                    res += y;
                } else
                if ((anc(v, u1) && anc(v, v1)) && (anc(v1, k) && anc(u1, k))){
                    res -= j.F;
                    res += y;
                } 
            }
            cout << res << endl;
        }
    }
}


Measured memory_bytes: 55084