#include <algorithm>
#include <climits>
#include <complex>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

// using
using namespace std;

// typedef
typedef long long ll;

// define
#define FOR(i, a, b, c) for (int i = (int)(a); i < (int)(b); i += (int)(c))
#define REP(i, n) FOR(i, 0, n, 1)
#define RFOR(i, a, b, c) for (int i = (int)(a); i >= (int)(b); i -= (int)(c))
#define RREP(i, n) RFOR(i, n, 0, 1)
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort(ALL(c))
#define REVERSE(c) reverse(ALL(c))
#define UNIQ(c) unique(ALL(c))
#define LB(c, x) lower_bound(c.begin(), c.end(), x)
#define UB(c, x) upper_bound(c.begin(), c.end(), x)
#define LI(c, x) distance(c.begin(), LB(c, x))
#define UI(c, x) distance(c.begin(), UB(c, x))

// functions
template <class T> T ceil(T a, T b) {
    return (a + b - 1) / b;
}
template <class T> T round(T a, T b) {
    return (a + b / 2) / b;
}
template <class T> T gcd(T a, T b) {
    return b ? gcd(b, a % b) : a;
}
template <class T> T lcm(T a, T b) {
    return a / gcd(a, b) * b;
}
template <class T> bool amax(T& a, const T& b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T> bool amin(T& a, const T& b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}
ll modpow(ll a, ll b, ll m) {
    if (b == 0) {
        return 1;
    } else if (b % 2 == 0) {
        ll h = modpow(a, b / 2, m);
        return h * h % m;
    } else {
        return a * modpow(a, b - 1, m) % m;
    }
}
ll comb(ll a, ll b, ll m) {
    if (b > a - b) {
        return comb(a, a - b, m);
    }
    ll c = 1, d = 1;
    REP(i, b) {
        c *= (a - i);
        d *= (b - i);
        c %= m;
        d %= m;
    }
    return c * modpow(d, m - 2, m) % m;
}

struct node {
    int to;
    int col;
    int dis;
};

struct query {
    int id;
    int col;
    int dis;
    int coef;
};

const int MAX_N = 100000;
const int MAX_LOGN = 20;
const int MAX_Q = 100000;

vector<vector<node>> G(MAX_N);
vector<vector<query>> qs(MAX_N);

vector<vector<int>> par(MAX_N, vector<int>(MAX_LOGN, -1));
vector<int> dep(MAX_N, 0);
vector<int> dis(MAX_N, 0);
vector<int> cnt(MAX_N, 0);
vector<int> sum(MAX_N, 0);

vector<int> res(MAX_Q, 0);

void init(int u, int p = -1, int d = 0) {
    if (p >= 0) {
        par[u][0] = p;
        dep[u] = dep[p] + 1;
        dis[u] = dis[p] + d;
    }
    for (auto g : G[u]) {
        int v = g.to;
        if (v != p) {
            init(v, u, g.dis);
        }
    }
}
void parent(int n) {
    REP(i, MAX_LOGN) {
        REP(j, n) {
            if (par[j][i] != -1) {
                par[j][i + 1] = par[par[j][i]][i];
            }
        }
    }
}
int lca(int u, int v) {
    if (dep[u] > dep[v]) {
        swap(u, v);
    }
    RREP(i, MAX_LOGN - 1) {
        if (((dep[v] - dep[u]) >> i) & 1) {
            v = par[v][i];
        }
    }
    if (u == v) {
        return u;
    }
    RREP(i, MAX_LOGN - 1) {
        if (par[u][i] != par[v][i]) {
            u = par[u][i];
            v = par[v][i];
        }
    }
    return par[u][0];
}
void dfs(int u, int p = -1) {
    for (auto q : qs[u]) {
        int diff = q.dis * cnt[q.col] - sum[q.col];
        res[q.id] += diff * q.coef;
    }
    for (auto g : G[u]) {
        int v = g.to;
        if (v == p) {
            continue;
        }
        cnt[g.col]++;
        sum[g.col] += g.dis;
        dfs(v, u);
        cnt[g.col]--;
        sum[g.col] -= g.dis;
    }
}

// main
int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    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, c, d});
        G[b].push_back({a, c, d});
    }
    init(0);
    parent(N);
    REP(i, Q) {
        int x, y, u, v;
        cin >> x >> y >> u >> v;
        u--, v--;
        int w = lca(u, v);
        qs[u].push_back({i, x, y, 1});
        qs[v].push_back({i, x, y, 1});
        qs[w].push_back({i, x, y, -2});
        res[i] = dis[u] + dis[v] - 2 * dis[w];
    }
    dfs(0);
    REP(i, Q) {
        cout << res[i] << endl;
    }
    return 0;
}


Measured memory_bytes: 34164