#include<bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define ll long long
#define all(a) a.begin(),a.end()
#define endl '\n'
#define y1 y12312123

using namespace std;

const int N = 1e5 + 3;
const int inf = 1e9 + 3;
const int md = 1e9 + 7;

struct edge{
    int to;
    int col;
    int len;
    int num;
};
struct ed{
    int x, y;
    int col;
    int len;
};

struct quer{
    int x, y;
    int v, u;
    int num;
};

int n, q, x, y, col, len, h[N], dist[N], tin[N], tout[N], timer;
int pr[N][17];
vector<edge> g[N];
vector<ed> edges[N];
vector<quer> queries[N];
int d[2][N];
int anss[N];

void dfs(int v, int p = 0){
    tin[v] = ++timer;
    pr[v][0] = p;
    for(int i = 1; i < 17; ++i)pr[v][i] = pr[pr[v][i - 1]][i - 1];
    for(int i = 0; i < g[v].size(); ++i){
        int to = g[v][i].to;
        if(to == p)continue;
        int len = g[v][i].len;
        dist[to] = dist[v] + len;
        h[to] = h[v] + 1;
        dfs(to, v);
    }
    tout[v] = timer;
}

int lca(int x, int y){
    if(h[x] < h[y])swap(x, y);
    int del = h[x] - h[y];
    for(int i = 16; i >= 0; i--){
        if(del & (1 << i))x = pr[x][i];
    }
    if(x == y)return x;
    for(int i = 16; i >= 0; i--){
        if(pr[x][i] != pr[y][i]){
            x = pr[x][i];
            y = pr[y][i];
        }
    }
    return pr[x][0];
}

void update(int z, int v, int x){
    while(v < N){
        d[z][v] += x;
        v |= (v + 1);
    }
}
int get(int z, int v){
    int res = 0;
    while(v >= 0){
        res += d[z][v];
        v = (v & (v + 1)) - 1;
    }
    return res;
}

int get_dist(int v, int y){
    return dist[v] - get(1, tin[v]) + get(0, tin[v]) * y;
}

main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

    cin >> n >> q;
    for(int i = 1; i < n; ++i){
        cin >> x >> y >> col >> len;
        g[x].pb({y, col, len});
        g[y].pb({x, col, len});
        edges[col].pb({x, y, col, len});
    }

    for(int i = 1; i <= q; ++i){
        int x, y, v, u;
        cin >> x >> y >> v >> u;
        queries[x].pb({x, y, v, u , i});
    }

    dfs(1);

    for(int i = 1; i < n; ++i){
        for(int j = 0; j < edges[i].size(); ++j){
            int x = edges[i][j].x;
            int y = edges[i][j].y;
            int len = edges[i][j].len;
            if(h[x] > h[y])swap(x, y);
            update(0, tin[y], 1);
            update(0, tout[y] + 1, -1);
            update(1, tin[y], len);
            update(1, tout[y] + 1, -len);
        }

        for(int j = 0; j < queries[i].size(); ++j){
            int y = queries[i][j].y;
            int v = queries[i][j].v;
            int u = queries[i][j].u;
            int lc = lca(v, u);
            anss[queries[i][j].num] = get_dist(v, y) + get_dist(u, y) - get_dist(lc, y) * 2;
        }

        for(int j = 0; j < edges[i].size(); ++j){
            int x = edges[i][j].x;
            int y = edges[i][j].y;
            int len = edges[i][j].len;
            if(h[x] > h[y])swap(x, y);
            update(0, tin[y], -1);
            update(0, tout[y] + 1, +1);
            update(1, tin[y], -len);
            update(1, tout[y] + 1, len);
        }
    }

    for(int i = 1; i <= q; ++i){
        cout << anss[i] << endl;
    }

}


Measured memory_bytes: 32108