#include <bits/stdc++.h>

#define fst(t) std::get<0>(t)
#define snd(t) std::get<1>(t)
#define thd(t) std::get<2>(t)
#define unless(p) if(!(p))
#define until(p) while(!(p))

using ll = std::int64_t;
using P = std::tuple<int,int>;
using T = std::tuple<int,int,int>;
using T4 = std::tuple<int,int,int,int>;

template <typename M>
struct SegmentTree{
    using T = typename M::type;

    int numLeaves;
    std::vector<T> data;
    
    SegmentTree(int n){
        numLeaves = 1;
        while(numLeaves < n){
            numLeaves *= 2;
        }
        
        data.resize(numLeaves * 2);
        std::fill(data.begin() + numLeaves, data.end(), M::identity());
        
        for(int i=numLeaves-1;i>0;--i){
            data[i] = M::bop(data[i*2], data[i*2+1]);
        }
    }

    template <typename F>
    SegmentTree(int n, F f){
        numLeaves = 1;
        while(numLeaves < n){
            numLeaves *= 2;
        }

        data.resize(numLeaves * 2);
        for(int i=0;i<n;++i){
            data[i + numLeaves] = std::move(f(i));
        }
        std::fill(data.begin() + numLeaves + n, data.end(), M::identity());

        for(int i=numLeaves-1;i>0;--i){
            data[i] = M::bop(data[i*2], data[i*2+1]);
        }
    }

    void set(int k, T v){
        k += numLeaves;
        data[k] = v;
        
        while(k > 1){
            k /= 2;
            data[k] = M::bop(data[k*2], data[k*2+1]);
        }
    }
    
    T product(int l, int r){
        l += numLeaves;
        r += numLeaves;
        
        T pl = M::identity(), pr = M::identity();
        for(;l<r;l/=2,r/=2){
            if(l & 1){
                pl = M::bop(pl, data[l]);
                l += 1;
            }
            if(r & 1){
                r -= 1;
                pr = M::bop(data[r], pr);
            }
        }
        
        return M::bop(pl, pr);
    }
    
    T at(int i){
        return data[i + numLeaves];
    }
};

struct M{
    using type = int;
    static type identity(){
        return 0;
    }
    static type bop(type &m1, type &m2){
        return m1 + m2;
    }
};

int N, Q;
std::vector<P> G[100100];
std::vector<T> CG[100100];
std::vector<T4> queries[100100];
int di[100100], de[100100], par[17][100100];
int l[100100], r[100100], res[100100];
SegmentTree<M> seg1(200100), seg2(200100);

void dfs(int v, int p, int &c){
    par[0][v] = p;
    l[v] = c++;
    
    for(P &e : G[v]){
        int w, d;
        std::tie(w, d) = e;

        if(w == p){
            continue;
        }

        di[w] = di[v] + d;
        de[w] = de[v] + 1;

        dfs(w, v, c);
    }

    r[v] = c++;
}

int LCA(int u, int v){
    if(de[u] < de[v]){
        std::swap(u, v);
    }
    int d = de[u] - de[v];
    
    for(int j=0;j<=16;++j){
        if(d >> j & 1){
            u = par[j][u];
        }
    }
    
    if(u != v){
        for(int j=16;j>=0;--j){
            if(par[j][u] != par[j][v]){
                u = par[j][u];
                v = par[j][v];
            }
        }
        
        u = par[0][u];
    }
    
    return u;
}

int main(){
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);

    std::cin >> N >> Q;

    for(int i=0;i<N-1;++i){
        int A, B, C, D;
        std::cin >> A >> B >> C >> D;

        G[A].emplace_back(B, D);
        G[B].emplace_back(A, D);
        CG[C].emplace_back(A, B, D);
    }

    for(int i=0;i<Q;++i){
        int x, y, u, v;
        std::cin >> x >> y >> u >> v;

        queries[x].emplace_back(y, u, v, i);
    }

    {
        int c = 0;
        dfs(1, -1, c);
    }

    for(int i=0;i<16;++i){
        for(int j=1;j<=N;++j){
            if(par[i][j] == -1){
                par[i+1][j] = -1;
            }else{
                par[i+1][j] = par[i][par[i][j]];
            }
        }
    }

    for(int i=1;i<=N;++i){
        for(auto &e : CG[i]){
            int v, w, d;
            std::tie(v, w, d) = e;

            if(di[v] < di[w]){
                std::swap(v, w);
            }

            seg1.set(l[v], seg1.at(l[v]) + 1);
            seg1.set(r[v], seg1.at(r[v]) - 1);
            seg2.set(l[v], seg2.at(l[v]) + d);
            seg2.set(r[v], seg2.at(r[v]) - d);
        }

        for(auto &q : queries[i]){
            int y, u, v, idx;
            std::tie(y, u, v, idx) = q;

            int w = LCA(u, v);
            
            // std::cout << "--" << std::endl;
            // std::cout << u << ", " << v << ", " << w << std::endl;
            // std::cout << di[u] << ", " << di[v] << ", " << di[w] << std::endl;
            // std::cout << seg2.product(0, l[u] + 1) << ", " << seg2.product(0, l[v] + 1) << ", " << seg2.product(0, l[w] + 1) << std::endl;
            // std::cout << seg1.product(0, l[u] + 1) << ", " << seg1.product(0, l[v] + 1) << ", " << seg1.product(0, l[w] + 1) << std::endl;

            res[idx] = (di[u] - 2 * di[w] + di[v]) - (seg2.product(0, l[u] + 1) - 2 * seg2.product(0, l[w] + 1) + seg2.product(0, l[v] + 1)) + (seg1.product(0, l[u] + 1) - 2 * seg1.product(0, l[w] + 1) + seg1.product(0, l[v] + 1)) * y;
        }

        for(auto &e : CG[i]){
            int v, w, d;
            std::tie(v, w, d) = e;

            if(di[v] < di[w]){
                std::swap(v, w);
            }

            seg1.set(l[v], seg1.at(l[v]) - 1);
            seg1.set(r[v], seg1.at(r[v]) + 1);
            seg2.set(l[v], seg2.at(l[v]) - d);
            seg2.set(r[v], seg2.at(r[v]) + d);
        }
    }

    for(int i=0;i<Q;++i){
        std::cout << res[i] << std::endl;
    }
}


Measured memory_bytes: 32436