#include <bits/stdc++.h>
using namespace std;
#define SELECTER(_1, _2, _3, SELECT, ...) SELECT
#define REP1(i, n) for(int (i)=0; (i)<(n); (i)++)
#define REP2(i, a, b) for(int (i)=(a); (i)<(b); (i)++)
#define REP(...) SELECTER(__VA_ARGS__, REP2, REP1,) (__VA_ARGS__)
#define MOD 1000000007

template <class T> ostream& operator<<(ostream& os, const vector<T>& v){ os << "{"; for(size_t i=0; i<v.size(); i++) os << v[i] << (i+1==v.size() ? "" : ", "); os << "}"; return os; }
template <class T, class U> ostream& operator<<(ostream& os, const pair<T, U>& p){ return os << "{" << p.first << ", " << p.second << "}"; }

vector<vector<tuple<int, int, int>>> G;
vector<tuple<int, int, int, int>> qs;
vector<int> dist;
vector<int> sm, nm;
vector<vector<int>> cols;
map<pair<int, int>, int> mp_sm, mp_nm;

class LCA{
    vector<int> dep;
    vector<vector<int>> par;
public:
    LCA(int N, vector<vector<int>> &G, int s) : dep(N), par(N){
        vector<bool> isVisited(N, false);
        isVisited[s] = true;
        dfs1(N, G, isVisited, s, 0);
    
        int maxdepth = *max_element(dep.begin(), dep.end());
        int M = 1;
        for(int fac=1;; fac*=2){
            if(fac >= maxdepth) break;
            M++;
        }
        for(int i=0; i<N; i++) par[i].resize(M);
        par[s][0] = s;
        fill(isVisited.begin(), isVisited.end(), false);
        isVisited[s] = true;
        dfs2(N, M, G, isVisited, s);
    }
    void dfs1(int N, vector<vector<int>> &G, vector<bool> &isVisited, int s, int d){
        dep[s] = d;
        for(int t : G[s]){
            if(isVisited[t]) continue;
            isVisited[t] = true;
            dfs1(N, G, isVisited, t, d+1);
        }
    }
    void dfs2(int N, int M, vector<vector<int>> &G, vector<bool> &isVisited, int s){
        for(int i=1; i<M; i++)
            par[s][i] = par[par[s][i-1]][i-1];

        for(int t : G[s]){
            if(isVisited[t]) continue;
            isVisited[t] = true;
            par[t][0] = s;
            dfs2(N, M, G, isVisited, t);
        }
    }

    int get(int u, int v){
        int M = par[0].size();
        if(dep[u] > dep[v]) swap(u, v);
        int diff = dep[v] - dep[u];
        vector<int> vec;
        for(int i=0; i<M; i++)
            if(diff & (1 << i)) vec.push_back(i);
        reverse(vec.begin(), vec.end());
        for(int x : vec)
            v = par[v][x];

        if(u == v) return u;
        while(par[u][0] != par[v][0]){
            for(int i=M-1; i>=0; i--){
                if(par[u][i] != par[v][i]){
                    u = par[u][i];
                    v = par[v][i];
                }
            }
        }
        return par[u][0];
    }
};

void dfs(int cur, int prv){
    for(int c : cols[cur]){
        mp_sm[make_pair(cur, c)] = sm[c];
        mp_nm[make_pair(cur, c)] = nm[c];
    }
    for(auto g : G[cur]){
        int nxt, c, d;
        tie(nxt, c, d) = g;
        if(nxt == prv) continue;
        dist[nxt] = dist[cur] + d;
        sm[c] += d;
        nm[c]++;
        dfs(nxt, cur);
        sm[c] -= d;
        nm[c]--;
    }
}

int main(){
    int N, Q;
    cin >> N >> Q;
    G.resize(N);
    qs.resize(Q);
    dist.resize(N);
    sm.resize(N);
    nm.resize(N);
    cols.resize(N);

    REP(i, N-1){
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        a--; b--; c--;
        G[a].push_back(make_tuple(b, c, d));
        G[b].push_back(make_tuple(a, c, d));
    }
    vector<vector<int>> G2(N);
    for(int a=0; a<N; a++){
        for(auto g : G[a]){
            int b, c, d;
            tie(b, c, d) = g;
            G2[a].push_back(b);
            G2[b].push_back(b);
        }
    }
    LCA lca(N, G2, 0);

    REP(i, Q){
        int x, y, u, v;
        cin >> x >> y >> u >> v;
        x--; u--; v--;
        qs[i] = make_tuple(x, y, u, v);
        cols[u].push_back(x);
        cols[v].push_back(x);
        int w = lca.get(u, v);
        cols[w].push_back(x);
    }

    dfs(0, -1);

    for(auto q : qs){
        int x, y, u, v;
        tie(x, y, u, v) = q;
        int w = lca.get(u, v);
        int d0 = dist[u] + dist[v] - 2 * dist[w];
        int d1 = mp_sm[make_pair(u, x)] + mp_sm[make_pair(v, x)] - 2 * mp_sm[make_pair(w, x)];
        int d2 = mp_nm[make_pair(u, x)] + mp_nm[make_pair(v, x)] - 2 * mp_nm[make_pair(w, x)];
        d2 *= y;
        int ans = d0 + d2 - d1;
        cout << ans << endl;
    }

    return 0;
}


Measured memory_bytes: 66488