#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
#define MAXN 100233
using namespace std;
int dep[MAXN], fa[MAXN], siz[MAXN], son[MAXN], top[MAXN];
struct pvp {
    int c, w, id, add;
};
vector<pvp> a[MAXN];
struct qwq {
    int nex, to, w, c;
} e[MAXN << 1];
int h[MAXN];
int tot = 0;
int sum[MAXN];
int ans[MAXN];
inline void add(int x, int y, int w, int c) {
    e[++tot].to = y;
    e[tot].nex = h[x];
    e[tot].w = w;
    e[tot].c = c;
    h[x] = tot;
}
void dfs_fir(int f, int x, int dept) {
    dep[x] = dept;
    fa[x] = f;
    //	printf("pwpwppwppwpwp:::%d %d\n",fa[x],x);
    siz[x] = 1;
    int maxn = -1;
    //	printf(":::::::::::::::::::::::::::::::%d\n",x);
    for (int i = h[x], y; i; i = e[i].nex) {
        y = e[i].to;
        if (y == f)
            continue;
        sum[y] = sum[x] + e[i].w;
        dfs_fir(x, y, dept + 1);
        //		printf("Y:::::%d   X::::::%d   sum[x]:::%d    e[i].w:::%d
        //sum[y]::::%d\n",y,x,sum[x],e[i].w,sum[y]);
        siz[x] += siz[y];
        if (siz[y] > maxn) {
            son[x] = y;
            maxn = siz[y];
        }
    }
}
void dfs_sec(int x, int tp) {
    top[x] = tp;
    if (!son[x])
        return;
    dfs_sec(son[x], tp);
    for (int i = h[x], y; i; i = e[i].nex) {
        y = e[i].to;
        if (y == fa[x] || y == son[x])
            continue;
        dfs_sec(y, y);
    }
}

inline int LCA(int x, int y) {
    while (top[x] != top[y]) {
        if (dep[top[x]] < dep[top[y]])
            swap(x, y);
        x = fa[top[x]];
    }
    if (dep[x] > dep[y])
        return y;
    return x;
}
int icnt[MAXN], wcnt[MAXN];
void dfs(int x) {
    //	printf(":::%d\n",x);
    for (int i = h[x], y; i; i = e[i].nex) {
        y = e[i].to;
        if (y == fa[x]) {
            continue;
        }
        icnt[e[i].c]++;
        wcnt[e[i].c] += e[i].w;
        dfs(y);
        icnt[e[i].c]--;
        wcnt[e[i].c] -= e[i].w;
    }
    for (int i = 0; i < a[x].size(); i++) {
        //	printf("qwq  I::::%d\n",i);
        ans[a[x][i].id] += (sum[x] * a[x][i].add);
        //		printf("add:::::: %d :: sum::%d  add::%d    wcnt:::%d      icnt:::%d      axiW:::%d
        //add:%d\n",x,sum[x],a[x][i].add,wcnt[a[x][i].c],icnt[a[x][i].c],a[x][i].w,a[x][i].add);
        ans[a[x][i].id] -= (wcnt[a[x][i].c] - icnt[a[x][i].c] * a[x][i].w) * a[x][i].add;
    }
    //	printf("END");
}

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int u, v, w, c;
    for (int i = 1; i < n; i++) {
        scanf("%d%d%d%d", &u, &v, &c, &w);
        add(u, v, w, c);
        add(v, u, w, c);
    }

    //	for (int i=1;i<=n;i++)
    //	{
    //		for (int j=h[i];j;j=e[j].nex)
    //		{
    //			printf("Edge::::%d %d\n",i,e[j].to);
    //		}
    //		}
    dfs_fir(1, 1, 1);
    dfs_sec(1, 1);

    //	for (int i=1;i<=n;i++) printf("%d ",fa[i]);
    //	return 0;

    for (int i = 1; i <= m; i++) {
        scanf("%d%d%d%d", &c, &w, &u, &v);

        //		printf("LCA::%d\n",LCA(u,v));

        a[u].push_back((pvp){ c, w, i, 1 });
        a[v].push_back((pvp){ c, w, i, 1 });
        a[LCA(u, v)].push_back((pvp){ c, w, i, -2 });
    }
    dfs(1);
    for (int i = 1; i <= m; i++) {
        printf("%d\n", ans[i]);
    }
    return 0;
}

Measured memory_bytes: 23028