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

struct HLDecomposition{
    vector<vector<int>> G;
    int N;
    vector<int> sz, in, out, head, rev, par;
 
    HLDecomposition(vector<vector<int>> G):
    G(G), N(G.size()), sz(G.size()), in(G.size()), out(G.size()), head(G.size()), rev(G.size()), par(G.size()) {
        build();
    }
 
    void dfs_sz(int i, int p){
        par[i] = p;
        sz[i] = 1;
        if(G[i].size() && G[i][0] == p) swap(G[i][0], G[i].back());
        for(auto& j : G[i]){
            if(j == p) continue;
            dfs_sz(j, i);
            sz[i] += sz[j];
            if(sz[G[i][0]] < sz[j]) swap(G[i][0], j);
        }
    }
 
    void dfs_hld(int i, int p, int& times){
        in[i] = times++;
        rev[in[i]] = i;
        for(auto& j : G[i]){
            if(j == p) continue;
            head[j] = (G[i][0]==j ? head[i] : j);
            dfs_hld(j, i, times);
        }
    }
 
    void build(){
        dfs_sz(0, -1);
        int t = 0;
        dfs_hld(0, -1, t);
    }
 
    int la(int v, int k){
        while(true){
            int u = head[v];
            if(in[v]-k >= in[u]) return rev[in[v]-k];
            k -= in[v]-in[u]+1;
            v = par[u];
        }
    }
 
    int lca(int u, int v){
        for( ; ; v=par[head[v]]){
            if(in[u] > in[v]) swap(u, v);
            if(head[u] == head[v]) return u;
        }
    }
 
    template<typename T>
    T query(int u, int v, T e, function<T(int, int)> get_between, function<T(T, T)> merge, bool edge=false){
        T l = e, r = e;
        for( ; ; v=par[head[v]]){
            if(in[u] > in[v]) swap(u, v), swap(l, r);
            if(head[u] == head[v]) break;
            l = merge(l, get_between(in[head[v]], in[v]));
        }
        return merge(l, merge(r, get_between(in[u]+edge, in[v])));
    }
};

template<typename T>
struct BIT {
    int n;
    vector<T> dat;

    BIT(int n=0){
        initialize(n);
    }

    void initialize(int nin){
        n = nin;
        dat.resize(n, 0);
    }

    T sum(int i){
        T s = 0;
        while(i >= 0){
            s += dat[i];
            i = (i & (i+1)) - 1;
        }
        return s;
    }

    T sum_between(int i, int j){
        return sum(j) - sum(i-1);
    }

    void plus(int i, T x){
        while(i < n){
            dat[i] += x;
            i |= i+1;
        }
    }

    // a[0]+...+a[ret] >= x
    int lower_bound(T x){
        int ret = -1;
        int k = 1;
        while(2*k <= n) k <<= 1;
        for( ;k>0; k>>=1){
            if(ret+k < n && dat[ret+k] < x){
                x -= dat[ret+k];
                ret += k;
            }
        }
        return ret + 1;
    }
};

int main(){
    int N, Q;
    cin >> N >> Q;
    vector<vector<int>> es(N);
    vector<vector<int>> edges[100000];
    for(int i=0; i<N-1; i++){
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        a--; b--; c--;
        es[a].push_back(b);
        es[b].push_back(a);
        edges[a].push_back({b, c, d});
        edges[b].push_back({a, c, d});
    }
    HLDecomposition hld(es);
    vector<int> V(N);
    vector<vector<int>> c2v(N);
    auto dfs = [&](auto&& dfs, int i, int p)->void{
        for(auto& v : edges[i]){
            int j = v[0], c = v[1], d = v[2];
            if(j == p) continue;
            V[j] = d;
            c2v[c].push_back(j);
            dfs(dfs, j, i);
        }
    };
    dfs(dfs, 0, -1);

    vector<vector<vector<int>>> qs(N);
    for(int i=0; i<Q; i++){
        int c, d, a, b;
        cin >> c >> d >> a >> b;
        c--; a--; b--;
        qs[c].push_back({d, a, b, i});
    }

    vector<int> ans(Q);
    BIT<int> bit_num(N), bit_sum(N);
    for(int i=0; i<N; i++) bit_sum.plus(hld.in[i], V[i]);
    for(int c=0; c<N; c++){
        for(int a : c2v[c]){
            bit_sum.plus(hld.in[a], -V[a]);
            bit_num.plus(hld.in[a], 1);
        }
        for(auto& v : qs[c]){
            int d = v[0], a = v[1], b = v[2], idx = v[3];
            int sum = hld.query<int>(a, b, 0, [&](int x, int y){ return bit_sum.sum_between(x, y); }, [](int a, int b){ return a+b;}, true);
            int num = hld.query<int>(a, b, 0, [&](int x, int y){ return bit_num.sum_between(x, y); }, [](int a, int b){ return a+b;}, true);
            ans[idx] = sum + num*d;

        }
        for(int a : c2v[c]){
            bit_sum.plus(hld.in[a], V[a]);
            bit_num.plus(hld.in[a], -1);
        }
    }
    for(int a : ans) cout << a << endl;
}


Measured memory_bytes: 45656