#include<bits/stdc++.h>

#define int long long
using namespace std;
#define rep(i, n) for(int i=0;i<(n);++i)
typedef pair<int, int> pii;
const int INF = 1l << 60;
#define u_b upper_bound
#define l_b lower_bound

int parent[20][100100];
int depth[100100];
vector<int> G[100100];
map<pii, pii> edge;//(a,b),(c,d) a<b
pii edgeToPar[100100];//pii(c,d)
int dist[100100];//根までの距離

int Length = 0;

void dfs(int v, int p, int d) {
    if (p != -1) {
        edgeToPar[v] = edge[pii(min(v, p), max(v, p))];
        Length += edgeToPar[v].second;
        dist[v] = Length;
    }
    parent[0][v] = p;
    depth[v] = d;
    for (int to:G[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v, d + 1);
    }
    if (p != -1)
        Length -= edgeToPar[v].second;
}

int sum[100100], num[100100];
vector<int> necessary_color[100100];
map<pii, int> sum2, num2;//key=(v,color)

void dfs2(int v, int p) {
    if (p != -1) {
        int color = edgeToPar[v].first;
        int length = edgeToPar[v].second;
        sum[color] += length;
        num[color] += 1;
    }
    for (int c:necessary_color[v]) {
        sum2[pii(v, c)] = sum[c];
        num2[pii(v, c)] = num[c];
    }
    for (int to:G[v]) {
        if (to == p)continue;
        dfs2(to, v);
    }
    if (p != -1) {
        int color = edgeToPar[v].first;
        int length = edgeToPar[v].second;
        sum[color] -= length;
        num[color] -= 1;
    }
}

void init(int V) {
    dfs(0, -1, 0);
    for (int k = 0; k + 1 < 20; ++k) {
        for (int v = 0; v < V; ++v) {
            if (parent[k][v] < 0) {
                parent[k + 1][v] = -1;
            } else {
                parent[k + 1][v] = parent[k][parent[k][v]];
            }
        }
    }
}

int Lca(int u, int v) {
    if (depth[u] > depth[v])swap(u, v);
    rep(k, 20) {
        if ((depth[v] - depth[u]) >> k & 1) {
            v = parent[k][v];
        }
    }
    if (v == u) {
        return v;
    }
    for (int k = 19; k >= 0; --k) {
        if (parent[k][u] != parent[k][v]) {
            u = parent[k][u];
            v = parent[k][v];
        }
    }
    int a = parent[0][u];
    return a;
}

struct Query {
    int x, y, u, v, lca;

    Query(int x, int y, int u, int v, int lca) : x(x), y(y), u(u), v(v), lca(lca) {}
};

vector<Query> queries;

signed main() {
    int N, Q;
    cin >> N >> Q;
    rep(i, N - 1) {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        --a, --b;
        G[a].push_back(b);
        G[b].push_back(a);
        edge[pii(min(a, b), max(a, b))] = pii(c, d);
    }
    init(N);

    rep(i, Q) {
        int x, y, u, v;
        cin >> x >> y >> u >> v;
        --u, --v;
        int lca = Lca(u, v);
        queries.emplace_back(x, y, u, v, lca);
        necessary_color[u].push_back(x);
        necessary_color[v].push_back(x);
        necessary_color[lca].push_back(x);
    }
    dfs2(0, -1);
    for (Query q:queries) {
        int x = q.x;
        int y = q.y;
        int u = q.u;
        int v = q.v;
        int lca = q.lca;
        int du = dist[u] - sum2[pii(u, x)] + y * num2[pii(u, x)];
        int dv = dist[v] - sum2[pii(v, x)] + y * num2[pii(v, x)];
        int dlca = dist[lca] - sum2[pii(lca, x)] + y * num2[pii(lca, x)];
        cout << du + dv - 2 * dlca << endl;
    }
    return 0;
}


Measured memory_bytes: 79016