//#include "bits/stdc++.h"

#define _USE_MATH_DEFINES
#include<cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <deque>
#include <algorithm>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <iterator>

using namespace std;

#define rep(i,a,b) for(int i=(a), i##_len=(b);i<i##_len;i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)

#define int ll
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair

//typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<double, double> pdd;
typedef vector< vector<int> > mat;

template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;
const double EPS = 1e-9;

struct Edge
{
	int s, t, cost, col;
	Edge(int s, int t, int cost, int col) :s(s), t(t), cost(cost), col(col) {}
	Edge() :Edge(-1, -1, -1, -1) {}
};

vector<Edge> G[100000];

class LCA {
public:
	int V, logV;
	vector<int> depth, len;
	vector<vector<int> > parent;

	LCA(int V) {
		this->V = V;
		logV = 0;
		while (V > (1LL << logV)) logV++;
		this->depth = vector<int>(V);
		this->len = vector<int>(V);
		this->parent = vector<vector<int> >(logV, vector<int>(V));
	}

	void init(int v, int par, int d, int l) {
		depth[v] = d;
		parent[0][v] = par;
		len[v] = l;
		for (int i = 0; i < (int)G[v].size(); i++) {
			int w = G[v][i].t;
			int lc = G[v][i].cost;
			if (w == par) continue;
			init(w, v, d + 1, lc + l);
		}
	}

	void build() {
		for (int k = 0; k + 1 < logV; k++) {
			for (int v = 0; v < V; v++) {
				if (parent[k][v] < 0) parent[k + 1][v] = -1;
				else parent[k + 1][v] = parent[k][parent[k][v]];
			}
		}
	}

	int query(int u, int v) {
		if (depth[u] > depth[v]) swap(u, v);
		for (int k = 0; k < logV; k++) {
			if ((depth[v] - depth[u]) >> k & 1)
				v = parent[k][v];
		}
		if (u == v) return u;

		for (int k = logV - 1; k >= 0; k--) {
			if (parent[k][u] != parent[k][v]) {
				u = parent[k][u];
				v = parent[k][v];
			}
		}
		return parent[0][u];
	}
};

map<int, pii> memo[100010];
int coln[100010];
int cold[100010];
int X[100010], Y[100010], U[100010], V[100010], PAR[100010];

void dfs(int v, int pre)
{
	for (auto& p : memo[v])
	{
		p.second.first = coln[p.first];
		p.second.second = cold[p.first];
	}

	for (auto& e : G[v])
	{
		if (e.t == pre)continue;
		coln[e.col]++;
		cold[e.col] += e.cost;
		dfs(e.t, v);
		coln[e.col]--;
		cold[e.col] -= e.cost;
	}
}

signed main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N, Q;
	cin >> N >> Q;
	int a, b, c, d;
	rep(i, 0, N-1)
	{
		cin >> a >> b >> c >> d;
		a--, b--;
		G[a].push_back(Edge(a, b, d, c));
		G[b].push_back(Edge(b, a, d, c));
	}

	LCA lca(N);
	lca.init(0, -1, 0, 0);
	lca.build();

	rep(i, 0, Q)
	{
		cin >> X[i] >> Y[i] >> U[i] >> V[i];
		U[i]--, V[i]--;
		PAR[i] = lca.query(U[i], V[i]);
		memo[U[i]][X[i]] = mp(0, 0);
		memo[V[i]][X[i]] = mp(0, 0);
		memo[PAR[i]][X[i]] = mp(0, 0);
	}

	dfs(0, -1);

	rep(i, 0, Q)
	{
		int ud = lca.len[U[i]] + memo[U[i]][X[i]].first*Y[i] - memo[U[i]][X[i]].second;
		int vd = lca.len[V[i]] + memo[V[i]][X[i]].first*Y[i] - memo[V[i]][X[i]].second;
		int pd = lca.len[PAR[i]] + memo[PAR[i]][X[i]].first*Y[i] - memo[PAR[i]][X[i]].second;
		cout << ud + vd - 2 * pd << endl;
	}

	return 0;
}

Measured memory_bytes: 52720