#include "bits/stdc++.h"
using namespace std;
#define pb push_back
#define fi first
#define se second
#define FF first
#define SS second
#define mp make_pair
#define ll long long
#define pii pair<ll,ll>
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define endl '\n'
#define fr(i, a, b) for(int i = a; i <= b; i++)
#define sz(x) (int)x.size()
typedef long double f80;
#define all(x) x.begin(), x.end()
const int mod = 1e9 + 7;

ll pwr(ll a, ll b) {
    a %= mod;
    ll ans = 1;
    while(b) {
        if(b & 1) ans = (ans * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }
    return ans;
}
const int N = 1e5 + 5;
const int LOGN = 17;

int dp[LOGN][N], depth[N];
int n, q;
vector<pair<int,pii>> g[N];

struct node {
    node *l, *r;
    pii p;
    node() {
        l = r = NULL;
        p = {0, 0};
    }
};

node *version[N];

inline pii operator + (const pii &a, const pii &b) {
    return {a.fi + b.fi, a.se + b.se};
}

inline pii operator - (const pii &a, const pii &b) {
    return {a.fi - b.fi, a.se - b.se};
}

node * L(node *r) {
    if(!r) return NULL;
    return r -> l;
}

node * R(node *r) {
    if(!r) return NULL;
    return r -> r;
}

pii V(node *r) {
    if(!r) return {0, 0};
    return r -> p;
}

void upd(node* &cur, node *prev, int s,int e,int idx, pii p) {
    cur = new node();
    cur -> p = V(prev) + p;
    if(s == e) return;
    int m = (s + e) >> 1;
    if(idx <= m) {
        upd(cur -> l, L(prev), s, m, idx, p);
        cur -> r = R(prev);
    }
    else {
        upd(cur -> r, R(prev), m + 1, e, idx, p);
        cur -> l = L(prev);
    }
}

void dfs(int u,int p) {
    dp[0][u] = p;
    depth[u] = depth[p] + 1;
    for(pair<int,pii> v : g[u]) {
        if(v.fi != p) {
            // cout << u << " " << v.fi << endl;
            upd(version[v.fi], version[u], 1, n, v.se.fi, {1, v.se.se});
            dfs(v.fi, u);
        }
    }
}

int lca(int u,int v) {
    if(depth[u] < depth[v]) swap(u, v);
    for(int k = LOGN - 1; k >= 0; k--) {
        if(depth[dp[k][u]] >= depth[v]) u = dp[k][u];
    }
    if(u == v) return u;
    for(int k = LOGN - 1; k >= 0; k--) {
        if(dp[k][u] != dp[k][v]) u = dp[k][u], v = dp[k][v];
    }
    return dp[0][u];
}

pii query(node *cur, int s,int e,int l,int r) {
    if(s > r || e < l || !cur) return {0, 0};
    if(l <= s && e <= r) return cur -> p;
    int m = (s + e) >> 1;
    return query(cur -> l, s, m, l, r) + query(cur -> r, m + 1, e, l, r);
}

signed main()
{
    #ifdef LOCAL
        freopen("inp.txt", "r", stdin);
        freopen("out.txt", "w", stdout);
    #endif
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    cin >> n >> q;
    fr(i, 1, n - 1) {
        int u, v, c, d;
        cin >> u >> v >> c >> d;
        g[u].pb({v, {c, d}});
        g[v].pb({u, {c, d}});
    }
    dfs(1, 0);
    fr(k, 1, LOGN - 1) {
        fr(i, 1, n) {
            dp[k][i] = dp[k - 1][dp[k - 1][i]];
        }
    }
    fr(i, 1, q) {
        int x, y, u, v;
        cin >> x >> y >> u >> v;
        int lc = lca(u, v);
        pii p1 = {0, 0}, p2 = {0, 0};
        int l = u, r = v;
        pii p = query(version[l], 1, n, 1, n);
        p1 = p1 + p;
        p = query(version[r], 1, n, 1, n);
        p1 = p1 + p;
        p = query(version[lc], 1, n, 1, n);
        p1 = p1 - p;
        p1 = p1 - p;
        p = query(version[l], 1, n, x, x);
        p2 = p2 + p;
        p = query(version[r], 1, n, x, x);
        p2 = p2 + p;
        p = query(version[lc], 1, n, x, x);
        p2 = p2 - p;
        p2 = p2 - p;
        cout << p1.se - p2.se + p2.fi * y << endl;
    }
    return 0;
}

Measured memory_bytes: 106880