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

#include<cmath>
#include<vector>
#include<cassert>
#include<numeric>
using ll=long long;
namespace ProconLib{

    template<class graph_t>
    class LCA{
        private:        
        static int safeLog2(int N){return std::ceil(std::log2(N+1))+1;}
        void dfs(int v,int pre,const graph_t& g);

        protected:
        int N;
        int logN;
        std::vector<std::vector<int>> par;
        std::vector<int> dep;

        public:
        LCA(std::vector<int> root,const graph_t &g);
        LCA(int root,const graph_t &g):LCA(std::vector<int>(1,root),g){};
        int query(int a,int b);
        int depth(int v){return dep[v];}
    };

    template<class graph_t>
    void LCA<graph_t>::dfs(int v,int pre,const graph_t& g){
        par[0][v]=pre;
        for(auto e:g[v]){
            if(e.to==pre) continue;
            par[0][e.to]=v;
            dep[e.to]=dep[v]+1;
            dfs(e.to,v,g);
        }
    }

    template<class graph_t>
    LCA<graph_t>::LCA(std::vector<int> roots,const graph_t &g): N(g.size()),
                                        logN(safeLog2(N)),
                                        par(logN,std::vector<int>(N)),
                                        dep(N,0)
    {
        std::iota(par[0].begin(),par[0].end(),0);
        for(auto root:roots){
            dep[root]=0;
            dfs(root,root,g);
        }
        for(int i=0;i+1<logN;i++){
            for(int j=0;j<N;j++){
                par[i+1][j]=par[i][par[i][j]];
            }
        }
    }


    template<class graph_t>
    int LCA<graph_t>::query(int a,int b){
        if(dep[a]<dep[b]) std::swap(a,b);
        int u=dep[a]-dep[b];
        for(int i=logN-1;i>=0;i--){
            if((u>>i)&1) a=par[i][a];
        }
        assert(dep[a]==dep[b]);
        if(a==b) return a;
        for(int i=logN-1;i>=0;i--){
            if(par[i][a]!=par[i][b]){
                a=par[i][a];
                b=par[i][b];
            }
        }
        assert(a!=b);
        a=par[0][a],b=par[0][b];
        if(a!=b) return -1; // if (g is a forest) and (a and b is disconnected).
        return a;
    }
    
}

using namespace ProconLib;
struct Edge{
    int to;
    ll c,d;
};
using Graph=vector<vector<Edge>>;

struct Query{
    int x,y;
    ll u,v;
    ll res=0;
};


class Solver{
    int N,Q;
    Graph g;
    vector<Query> qs;
    vector<ll> cnt;
    vector<ll> sum;
    vector<vector<int>> xyqids;
    vector<vector<int>> lcaqids;

    void dfs(int v,int pre,int dep){
        for(auto id:xyqids[v]){
            qs[id].res+=dep;
            qs[id].res-=sum[qs[id].u];
            qs[id].res+=cnt[qs[id].u]*qs[id].v;
            // cerr<<"#"<<id<<" "<<v<<" "<<qs[id].res<<endl;
        }
        for(auto id:lcaqids[v]){
            qs[id].res-=2*dep;
            qs[id].res+=2*sum[qs[id].u];
            qs[id].res-=2*cnt[qs[id].u]*qs[id].v;
            // cerr<<"$"<<id<<" "<<v<<" "<<qs[id].res<<endl;
        }
        for(auto& e:g[v]){
            if(e.to==pre) continue;
            cnt[e.c]++;
            sum[e.c]+=e.d;
            dfs(e.to,v,dep+e.d);
            cnt[e.c]--;
            sum[e.c]-=e.d;
        }
    }
    public:
    Solver(int N,int Q):N(N),Q(Q),g(N),qs(Q),xyqids(N),lcaqids(N),cnt(N),sum(N){
        for(int i=0;i+1<N;i++){
            int a,b,c,d;
            cin>>a>>b>>c>>d;
            a--,b--;
            g[a].push_back(Edge{b,c,d});
            g[b].push_back(Edge{a,c,d});
        }
        for(int i=0;i<Q;i++) cin>>qs[i].u>>qs[i].v>>qs[i].x>>qs[i].y,qs[i].x--,qs[i].y--;
        // cerr<<"INPUT"<<endl;
    }
    void init(){
        LCA<Graph> lca(0,g);
        for(int i=0;i<Q;i++){
            // cerr<<qs[i].x<<" "<<qs[i].y<<endl;
            xyqids[qs[i].x].push_back(i);
            xyqids[qs[i].y].push_back(i);
            // cerr<<"#1"<<endl;
            lcaqids[lca.query(qs[i].x,qs[i].y)].push_back(i);
            // cerr<<"#2"<<endl;
        }
        // cerr<<"INIT"<<endl;
    }

    void solve(){
        dfs(0,-1,0);
        for(int i=0;i<Q;i++){
            cout<<qs[i].res<<endl;
        }
    }
};

int main(){
    int N,Q;
    cin>>N>>Q;
    Solver solver(N,Q);
    solver.init();
    solver.solve();
    return 0;
}


Measured memory_bytes: 35320