#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; (i) < (int) (n); (i) ++)
using namespace std;

struct LowestCommonAncestorTree {
        const int LOGM = 30;
        vector<int> depth;
        vector<vector<int>> parent;
        LowestCommonAncestorTree(int root, const vector<vector<int>> &g) {
                int n = g.size();
                depth.resize(n);
                parent.resize(LOGM);
                for (int i = 0; i < LOGM; i ++) parent[i].resize(n);
                function<void (int, int, int)> dfs = [&](int u, int prev, int d) {
                        parent[0][u] = prev;
                        depth[u] = d;
                        for (auto v : g[u]) if (v != prev) dfs(v, u, d + 1);
                };
                dfs(root, -1, 0);
                for (int k = 0; k < LOGM - 1; k ++) {
                        for (int i = 0; i < n; i ++) {
                                if (parent[k][i] < 0) parent[k + 1][i] = -1;
                                else parent[k + 1][i] = parent[k][parent[k][i]];
                        }
                }
        }
        int lca(int u, int v) { 
                if (depth[u] > depth[v]) swap(u, v);
                for (int k = 0; k < LOGM; k ++) {
                        if ((depth[v] - depth[u]) >> k & 1) { 
                                v = parent[k][v];
                        }
                }
                if (u == v) return u;
                for (int k = LOGM - 1; k >= 0; k --) {
                        if (parent[k][u] != parent[k][v]) {
                                u = parent[k][u];
                                v = parent[k][v];
                        }
                }
                return parent[0][u];
        }
        int dist(int u, int v) {
                return depth[u] + depth[v] - 2 * depth[lca(u, v)];
        }
};

int main() {
        int n, q;
        scanf("%d%d", &n, &q);
        vector<vector<tuple<int, int, int>>> g(n);
        vector<vector<int>> tr(n);
        rep(i, n - 1) {
                int a, b, c, d;
                scanf("%d%d%d%d", &a, &b, &c, &d);
                a --, b --, c --;
                g[a].push_back(make_tuple(b, c, d));
                g[b].push_back(make_tuple(a, c, d));
                tr[a].push_back(b);
                tr[b].push_back(a);
        }
        LowestCommonAncestorTree tree(0, tr);
        vector<int> x(q), y(q), u(q), v(q), l(q);
        vector<vector<int>> query(n);
        rep(i, q) {
                scanf("%d%d%d%d", &x[i], &y[i], &u[i], &v[i]);
                x[i] --, u[i] --, v[i] --;
                l[i] = tree.lca(u[i], v[i]);
                query[u[i]].push_back(x[i]);
                query[v[i]].push_back(x[i]);
                query[l[i]].push_back(x[i]);
        }
        rep(i, n) {
                sort(query[i].begin(), query[i].end());
                query[i].erase(unique(query[i].begin(), query[i].end()), query[i].end());
        }
        vector<map<int, pair<int, long long>>> r(n);
        vector<long long> dist(n);
        function<void (int, int, map<int, pair<int, long long>> &)> dfs = [&](int u, int prev, map<int, pair<int, long long>> &mp) {
                for (auto it : query[u]) {
                        r[u][it] = mp[it];
                }
                for (auto e : g[u]) {
                        int v, c, d;
                        tie(v, c, d) = e;
                        if (v == prev) continue;
                        dist[v] = dist[u] + d;
                        mp[c].first ++;
                        mp[c].second += d;
                        dfs(v, u, mp);
                        mp[c].first --;
                        mp[c].second -= d;
                }
        };
        map<int, pair<int, long long>> mp;
        dfs(0, -1, mp);
        rep(i, q) {
                long long ll = dist[l[i]] - r[l[i]][x[i]].second + (long long) r[l[i]][x[i]].first * y[i];
                long long ul = dist[u[i]] - r[u[i]][x[i]].second + (long long) r[u[i]][x[i]].first * y[i];
                long long vl = dist[v[i]] - r[v[i]][x[i]].second + (long long) r[v[i]][x[i]].first * y[i];
                long long ans = ul + vl - 2 * ll;
                printf("%lld\n", ans);
        }
        return 0;
}


Measured memory_bytes: 63160