#include <bits/stdc++.h>
using namespace std;

struct LCA{
    static const int BITLEN_MAX = 30;
    vector<int> parent[BITLEN_MAX];
    vector<int> depth;
    int bitlen;

    void initialize(int N, const vector<int> edges[]){
        int root = 0;
        bitlen = 1;
        while((1<<bitlen) < N) bitlen += 1;
        for(int i=0; i<bitlen; i++) parent[i].resize(N);
        depth.resize(N, -1);

        dfs(root, -1, 0, edges);
        for(int k=0; k<bitlen-1; k++){
            for(int v=0; v<N; v++){
                if(depth[v] == -1) continue;
                if(parent[k][v] < 0){
                    parent[k+1][v] = -1;
                }else{
                    parent[k+1][v] = parent[k][parent[k][v]];
                }
            }
        }
    }

    void dfs(int v, int p, int d, const vector<int> edges[]){
        parent[0][v] = p;
        depth[v] = d;
        for(auto u : edges[v]){
            if(u != p) dfs(u, v, d+1, edges);
        }
    }

    int calc_lca(int u, int v){
        if(depth[u] > depth[v]) swap(u, v);
        for(int k=0; k<bitlen; k++){
            if( ((depth[v]-depth[u]) >> k) & 1 ) v = parent[k][v];
        }
        if(u == v) return u;
        for(int k=bitlen-1; k>=0; k--){
            if(parent[k][u] != parent[k][v]){
                u = parent[k][u];
                v = parent[k][v];
            }
        }
        return parent[0][u];
    }

    int calc_dist(int u, int v){
        int l = calc_lca(u, v);
        return depth[u] + depth[v] - depth[l]*2;
    }
};


int N;
vector<vector<int>> edges[100000];
vector<int> edges2[100000];  // LCA用、頂点情報だけ

vector<int> need[100000];  // need[i]: 頂点iについて値が必要になる色たち
map<int, int> res_num[100000], res_sum[100000];  // res_num[i][c]: 頂点iから根までの色cの辺の本数。res_sumはその長さ合計

int dist[100000];  // 根からの距離
int now_num[100000], now_sum[100000];  // now_num[c]: 今見ている頂点から根までの色cの辺の本数。now_sumはその長さ合計

void dfs(int i, int p){
    for(int c : need[i]){
        res_num[i][c] = now_num[c];
        res_sum[i][c] = now_sum[c];
    }

    for(auto& e : edges[i]){
        int j = e[0], c = e[1], d = e[2];
        if(j == p) continue;

        dist[j] = dist[i] + d;
        now_num[c]++;
        now_sum[c] += d;
        dfs(j, i);
        now_num[c]--;
        now_sum[c] -= d;
    }
}

int main(){
    int Q;
    cin >> N >> Q;
    for(int i=0; i<N-1; i++){
        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});
        edges2[a].push_back(b);
        edges2[b].push_back(a);
    }

    LCA lca;
    lca.initialize(N, edges2);

    int X[100000], Y[100000], U[100000], V[100000], L[100000];
    for(int i=0; i<Q; i++){
        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]);
    }

    dfs(0, -1);

    for(int i=0; i<Q; i++){
        int x = X[i], y = Y[i], u = U[i], v = V[i], l = L[i];

        int du = dist[u] - res_sum[u][x] + res_num[u][x] * y;
        int dv = dist[v] - res_sum[v][x] + res_num[v][x] * y;
        int dl = dist[l] - res_sum[l][x] + res_num[l][x] * y;
        int ans = du + dv - 2*dl;
        cout << ans << endl;
    }
    return 0;
}


Measured memory_bytes: 73268