#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...) do {} while (0)
#endif
#include<cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}

int N, Q;

struct Edge {
    int to;
    int color;
    int length;
    Edge() {}
    Edge(int t, int c, int l) {
	to = t;
	color = c;
	length = l;
    }
};
vector<Edge> G[100011];

int par[18][100011];
int depth[100011];

void dfs0(int v, int p) {
    EACH (e, G[v]) if (e->to != p) {
	par[0][e->to] = v;
	depth[e->to] = depth[v] + 1;
	dfs0(e->to, v);
    }
}

int lca(int x, int y) {
    if (depth[x] > depth[y]) swap(x, y);
    for (int t=0; depth[y]>depth[x]; t++) {
	if ((depth[y]-depth[x])>>t&1) {
	    y = par[t][y];
	}
    }
    if (x == y) return x;
    for (int t=18; t--;) {
	if (par[t][x] != par[t][y]) {
	    x = par[t][x];
	    y = par[t][y];
	}
    }
    return par[0][x];
}

struct Hint {
    int idx;
    char type;
    int color;
    int mul;
    Hint(){}
    Hint(int i, char t, int c, int m) {
	idx = i;
	type = t;
	color = c;
	mul = m;
    }
};
vector<Hint> H[100011];
LL ans[100011];
LL sum[100011];
LL cnt[100011];

void dfs1(int v, int p, LL d) {
    EACH (e, H[v]) {
	if (e->type == 'd') {
	    ans[e->idx] += d * e->mul;
	} else if (e->type == 's') {
	    ans[e->idx] += sum[e->color] * e->mul;
	} else {
	    ans[e->idx] += cnt[e->color] * e->mul;
	}
    }

    EACH (e, G[v]) if (e->to != p) {
	sum[e->color] += e->length;
	cnt[e->color] ++;
	dfs1(e->to, v, d + e->length);
	sum[e->color] -= e->length;
	cnt[e->color] --;
    }
}

void MAIN() {
    scanf("%d%d", &N, &Q);
    REP (i, N-1) {
	int a, b, c, d;
	scanf("%d%d%d%d", &a, &b, &c, &d);
	a--; b--; c--;
	G[a].emplace_back(b, c, d);
	G[b].emplace_back(a, c, d);
    }

    dfs0(0, 0);
    REP (t, 17) REP (v, N) par[t+1][v] = par[t][par[t][v]];

    REP (i, Q) {
	int x, y, u, v;
	scanf("%d%d%d%d", &x, &y, &u, &v);
	x--;
	u--;
	v--;

	int z = lca(u, v);

	H[u].emplace_back(i, 'd', 0, 1);
	H[u].emplace_back(i, 's', x, -1);
	H[u].emplace_back(i, 'c', x, y);

	H[v].emplace_back(i, 'd', 0, 1);
	H[v].emplace_back(i, 's', x, -1);
	H[v].emplace_back(i, 'c', x, y);

	H[z].emplace_back(i, 'd', 0, -2);
	H[z].emplace_back(i, 's', x, 2);
	H[z].emplace_back(i, 'c', x, -2*y);
	//ans[i] = dist[u] + dist[v] - dist[z] * 2;
	//ans[i] -= s(u, x) + s(v, x) - s(z, x) * 2;
	//ans[i] += (c(u, x) + c(v, x) - c(z, x) * 2) * y;
    }

    dfs1(0, 0, 0);
    REP (i, Q) printf("%lld\n", ans[i]);
}

int main() {
    int TC = 1;
//    scanf("%d", &TC);
    REP (tc, TC) MAIN();
    return 0;
}



Measured memory_bytes: 43504