#include <bits/stdc++.h>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <iostream>

#include <bitset>
#include <cassert>
#include <queue>
#include <random>
#include <stack>
#include <iomanip>

using namespace std;

#define rep(i, n) for (ll i = 0; i < (ll)n; i++)
#define repf(i, a, b) for (ll i = (ll)a; i < (ll)b; i++)
#define repr(i, a, b) for (ll i = (ll)a; i > (ll)b; i--)

#define repv(x, arr) for (auto &x : arr)
#define all(v) (v).begin(), (v).end()
#define vec(name, num) vector<ll> name((num), 0);
#define mp(a, b) make_pair(a, b)
#define op(i) cout << (i) << endl;
#define F first
#define S second

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;
typedef vector<ll> vll;
typedef vector<vll> vvll;

const ll mod = 1e9 + 7;
const int infi = 2147483647;
const ll infl = 1e17;

struct LCA{
    int logN;
    vector<int> parent[30];
    vector<int> depth;

    void __init__(int N,const vector<int> edges[]){
        logN = 0;
        while ((1<<logN)<N)
            logN++;
        depth.resize(N,-1);
        rep(k, logN) parent[k].resize(N,-1);
        dfs(0, -1, 0, edges);
        repf(k,1,logN){
            rep(v,N){
                if (parent[k-1][v]<0)
                    parent[k][v] = -1;
                else
                    parent[k][v] = parent[k - 1][parent[k - 1][v]];
            }
        }
    }
    void dfs(int now,int bef,int d,const vector<int> edges[]){
        depth[now]=d;
        parent[0][now] = bef;
        for (auto nex:edges[now]){
            if(nex!=bef){
                dfs(nex, now, d + 1, edges);
            }
        }
    }

    int calc_lca(int u,int v){
        if (depth[u]>depth[v])
            swap(u, v);
        rep(k,logN){
            if (((depth[v]-depth[u])>>k)&1){
                v = parent[k][v];
            }
        }
        if (u==v)
            return v;
        repr(k,logN-1,-1){
            if (parent[k][u]!=parent[k][v]){
                u = parent[k][u];
                v = parent[k][v];
            }
        }
        return parent[0][u];
    }
};

int n,q;
vector<vector<int>> edges[100005];
vector<int> edgeslca[100005];
int X[100005], Y[1000005], U[100005], V[100005], L[100005];
vector<int> need[100005];
map<int, int> res_sum[100005], res_num[100005];
int now_sum[100005], now_num[100005];
int dist[100005];

void euler_tour(int now,int bef){
    for (auto col:need[now]){
        res_sum[now][col] = now_sum[col];
        res_num[now][col] = now_num[col];
    }
    for (auto p:edges[now]){
        int nex = p[0], c = p[1], d = p[2];
        if (nex==bef)
            continue;
        dist[nex] = dist[now] + d;
        now_sum[c] += d;
        now_num[c]++;
        euler_tour(nex, now);
        now_sum[c] -= d;
        now_num[c]--;
    }
}

int main()
{
    cin >> n >> q;
    rep(i,n-1){
        int a,b,c,d;
        cin >> a >> b >> c >> d;
        a--;
        b--;
        c--;
        edges[a].push_back({b, c, d});
        edges[b].push_back({a, c, d});
        edgeslca[a].push_back(b);
        edgeslca[b].push_back(a);
    }
    
    LCA lca;
    lca.__init__(n, edgeslca);
    rep(i,q){
        cin >> X[i] >> Y[i] >> U[i] >> V[i];
        X[i]--;
        U[i]--;
        V[i]--;
        L[i] = lca.calc_lca(U[i], V[i]);
        need[U[i]].push_back(X[i]);
        need[V[i]].push_back(X[i]);
        need[L[i]].push_back(X[i]);
    }
    dist[0] = 0;
    euler_tour(0, -1);
    rep(i,q){
        int du = dist[U[i]] - res_sum[U[i]][X[i]] + Y[i] * res_num[U[i]][X[i]];
        int dv = dist[V[i]] - res_sum[V[i]][X[i]] + Y[i] * res_num[V[i]][X[i]];
        int dl = dist[L[i]] - res_sum[L[i]][X[i]] + Y[i] * res_num[L[i]][X[i]];
        cout << du + dv - 2 * dl << endl;
    }
}


Measured memory_bytes: 78004