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

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

#define p_ary(ary,a,b,i) do { cout << "["; for (int (i) = (a);(i) < (b);++(i)) cout << ary[(i)] << ((b)-1 == (i) ? "" : ", "); cout << "]\n"; } while(0)
#define p_map(map,it) do {cout << "{";for (auto (it) = map.begin();;++(it)) {if ((it) == map.end()) {cout << "}\n";break;}else cout << "" << (it)->first << "=>" << (it)->second << ", ";}}while(0)

struct edge {
    int to,w,c;
};

void dfs(vector<vector<int>>& anc,vector<vector<edge>>& G,vector<int>& depth,vector<int>& dist,int i,int p = -1) {
    for (edge& e : G[i]) if (e.to != p) {
        anc[e.to].push_back(i);
        depth[e.to] = depth[i]+1;
        dist[e.to] = dist[i]+e.w;
        dfs(anc,G,depth,dist,e.to,i);
    }
}

void pretreatment(vector<vector<int>>& anc,vector<vector<edge>>& G,vector<int>& depth,vector<int>& dist,int k) {
    dfs(anc,G,depth,dist,k);
    depth[k] = 0;
    dist[k] = 0;
    int n = anc.size();
    for (int i = 0;i < 20;++i) {
        for (int j = 0;j < n;++j) {
            if (anc[j].size() < i+1 || anc[anc[j][i]].size() < i+1) continue;
            anc[j].push_back(anc[anc[j][i]][i]);
        }
    }
}

int lca(vector<vector<int>>& anc,vector<int>& depth,vector<int>& dist,int i,int j) {
    if (depth[i] > depth[j]) swap(i,j);
    while (depth[i] < depth[j]) {
        for (int k = anc[j].size()-1;k >= 0;--k) if (depth[anc[j][k]] >= depth[i]) {
            j = anc[j][k];
            break;
        }
    }
    while (i != j) {
        for (int k = anc[i].size()-1;k >= 0;--k) {
            if (anc[i][k] != anc[j][k]) {
                i = anc[i][k];
                j = anc[j][k];
                break;
            } else if (k == 0) {
                i = j = anc[i][0];
            }
        }
    }
    return i;
}

int calc_dist(vector<vector<int>>& anc,vector<int>& depth,vector<int>& dist,int i,int j) {
    return dist[i]+dist[j]-dist[lca(anc,depth,dist,i,j)]*2;
}

void dfs2(vector<vector<edge>>& G,vector<vector<P>>& num,vector<vector<P>>& sum,vector<int>& l,int i,int p,int& cnt) {
    for (edge& e : G[i]) if (e.to != p) {
        num[e.c].push_back(P(cnt,1));
        sum[e.c].push_back(P(cnt,e.w));
        l[e.to] = cnt;
        cnt++;
        dfs2(G,num,sum,l,e.to,i,cnt);
        num[e.c].push_back(P(cnt,-1));
        sum[e.c].push_back(P(cnt,-e.w));
        cnt++;
    }
}

int main() {
    int n,q;
    cin >> n >> q;
    vector<int> depth(n),dist(n),l(n,-1);
    vector<vector<int>> anc(n);
    vector<vector<P>> num(n),sum(n);
    vector<vector<edge>> G(n);
    for (int i = 0;i < n-1;++i) {
        int u,v,c,w;
        cin >> u >> v >> c >> w;
        u--;v--;
        G[u].push_back(edge{v,w,c});
        G[v].push_back(edge{u,w,c});
    }
    pretreatment(anc,G,depth,dist,0);
    int cnt = 1;
    l[0] = 0;
    for (int i = 0;i < n;++i) num[i].push_back(P(0,0));
    for (int i = 0;i < n;++i) sum[i].push_back(P(0,0));
    dfs2(G,num,sum,l,0,-1,cnt);
    for (int i = 0;i < n;++i) for (int j = 1;j < sum[i].size();++j) sum[i][j].second += sum[i][j-1].second;
    for (int i = 0;i < n;++i) for (int j = 1;j < num[i].size();++j) num[i][j].second += num[i][j-1].second;
    for (int i = 0;i < q;++i) {
        int x,y,u,v;
        scanf("%d%d%d%d",&x,&y,&u,&v);
        u--;v--;
        int w = lca(anc,depth,dist,u,v);
        int a = upper_bound(num[x].begin(),num[x].end(),P(l[u],1<<20))-num[x].begin()-1;
        int b = upper_bound(num[x].begin(),num[x].end(),P(l[v],1<<20))-num[x].begin()-1;
        int c = upper_bound(num[x].begin(),num[x].end(),P(l[w],1<<20))-num[x].begin()-1;
        cout << (dist[u]-sum[x][a].second+num[x][a].second*y)+(dist[v]-sum[x][b].second+num[x][b].second*y)-(dist[w]-sum[x][c].second+num[x][c].second*y)*2 << "\n";
    }
    return 0;
}

Measured memory_bytes: 42732