#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>
#include <queue>
#include <set>
#include <algorithm>
#include <string>
#include <math.h>
#include <limits.h>
#include <stack>
#include <complex>
#include <stdlib.h>
#include <stdio.h>
#include <functional>
#include <cfloat>
#include <math.h>
#include <numeric>
#include <string.h>
#include <sys/time.h>
#include <random>


#define fs first
#define sc second

using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef pair<ll, ll> P;


class Graph{
    struct edge{
        int vertice;
        ll weight;
        int color;
    };

    vector<vector<edge>> g;
    unsigned int n;

public:
    Graph(unsigned int n): n{n}{
        g.resize(n);
    }

//    void add_edge(int u, int v){
//        g[u].emplace_back(edge{v, 1});
//    };

    void add_edge(int u, int v, ll w, int c){
        g[u].emplace_back(edge{v, w, c});
    }

    vector<edge>& get_edge(int v){
        return g[v];
    }

    unsigned int get_num_vertices(){
        return n;
    }

    unsigned int size(){
        return n;
    }

    vector<edge>& operator[](int v){
        return get_edge(v);
    }
};


class LCA{
    Graph g{0};
    int root;
    vector<vector<int>> parent;
    vector<int> depth;
    int n, log_n;

public:
    LCA(Graph& g2){
        root = 0;
        g = g2;
        init();
    }

    LCA(Graph& g2, int root): root(root){
        g = g2;
        init();
    }

    void dfs(int v, int p, int d){
        parent[0][v] = p;
        depth[v] = d;
        for(auto u: g[v]){
            if(u.vertice != p){
                dfs(u.vertice, v, d+1);
            }
        }
    }

    void init(){
        n = g.size();
        log_n = 2;
        int tmp_n = 1;
        while(tmp_n < n){
            tmp_n *= 2;
            log_n++;
        }

        parent = vector<vector<int>>(log_n, vector<int>(n, 0));
        depth = vector<int>(n, 0);

        dfs(root, -1, 0);
        for(int k = 0; k + 1 < log_n; k++){
            for(int v = 0; v < n; v++){
                if(parent[k][v] < 0) parent[k+1][v] = -1;
                else parent[k+1][v] = parent[k][parent[k][v]];
            }
        }
    }

    /**
     *
     * @param u
     * @param v
     * @return 頂点uと頂点vのLCA
     */
    int lca(int u, int v){
        if(depth[u] > depth[v]){
            swap(u, v);
        }
//        cout << u << " " << v << endl;

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

        return parent[0][u];
    }

    int getDepth(int v){
        return depth[v];
    }

};



map<int, P> mp[101000];
vector<ll> cost(101000, 0);


void addColor(int v, int c, ll weight){
    cout << v << " " << c << " " << weight << endl;
    if(mp[v].find(c) == mp[v].end()){
        mp[v][c] = P(1, weight);
    }
    else{
        mp[v][c].fs += 1;
        mp[v][c].sc += weight;
    }
}


P getColor(int v, int c){
    if(mp[v].find(c) == mp[v].end()){
        return P(0, 0);
    }
    else{
        return mp[v][c];
    }
}

vector<int> info[101000];
vector<map<int, P>> coloredInfo(101000, map<int, P>());

void dfs(int v, int prev, Graph& g, ll costTmp, vector<P>& vec){
    cost[v] = costTmp;
    for(auto c: info[v]) {
        coloredInfo[v][c] = vec[c];
    }

    for(auto e: g[v]) {
        if (e.vertice == prev) continue;
        vec[e.color].fs++;
        vec[e.color].sc += e.weight;
        dfs(e.vertice, v, g, costTmp + e.weight, vec);
        vec[e.color].fs--;
        vec[e.color].sc -= e.weight;
    }
}


int main(){
    uint n, q; cin >> n >> q;

    Graph g(n);
    for(int i = 0; i < n-1; i++){
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        a--; b--;
        g.add_edge(a, b, d, c);
        g.add_edge(b, a, d, c);
    }
    LCA lca(g);

    vector<int> uList(q, 0), vList(q, 0), xList(q, 0), yList(q, 0);
    vector<int> pList(q, 0);
    for(int i = 0; i < q; i++) {
        cin >> xList[i] >> yList[i] >> uList[i] >> vList[i];
        uList[i]--; vList[i]--;
        info[uList[i]].push_back(xList[i]);
        info[vList[i]].push_back(xList[i]);
        int p = lca.lca(uList[i], vList[i]);
        pList[i] = p;
        info[p].push_back(xList[i]);
    }
    vector<P> vec = vector<P>(n, P(0, 0));
    dfs(0, 0, g, 0, vec);

    for(int i = 0; i < q; i++) {
        int u = uList[i], v = vList[i], x = xList[i], y = yList[i], p = pList[i];
        int res = cost[u] + cost[v] - 2 * cost[p];
        int edgeNum = coloredInfo[u][x].fs + coloredInfo[v][x].fs - 2 * coloredInfo[p][x].fs;
        int edgeWeight = coloredInfo[u][x].sc + coloredInfo[v][x].sc - 2 * coloredInfo[p][x].sc;
        res += y * edgeNum - edgeWeight;
        cout << res << endl;
    }


    return 0;
}

Measured memory_bytes: 65528