//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops")
//#pragma GCC target("avx,avx2")
//#pragma GCC target("avx2")
//#pragma GCC optimize("O3")

//# include <x86intrin.h>
# include <bits/stdc++.h>

# include <ext/pb_ds/assoc_container.hpp>
# include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;
 
template<typename T> using ordered_set = tree <T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define _USE_MATH_DEFINES_
#define ll long long
#define ld long double
#define Accepted 0
#define pb push_back
#define mp make_pair
#define sz(x) (int)(x.size())
#define every(x) x.begin(),x.end()
#define F first
#define S second
#define lb lower_bound
#define ub upper_bound
#define For(i,x,y)  for (ll i = x; i <= y; i ++) 
#define FOr(i,x,y)  for (ll i = x; i >= y; i --)
#define SpeedForce ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
// ROAD to...                                                                                                                                                                                                                Red

void setIn(string s) { freopen(s.c_str(),"r",stdin); }
void setOut(string s) { freopen(s.c_str(),"w",stdout); }
void setIO(string s = "") {
	// cin.exceptions(cin.failbit); 
	// throws exception when do smth illegal
	// ex. try to read letter into int
	if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
}

const double eps = 0.000001;
const ld pi = acos(-1);
const int maxn = 1e7 + 9;
const int mod = 1e9 + 7;
const ll MOD = 1e18 + 9;
const ll INF = 1e18 + 123;
const int inf = 2e9 + 11;
const int mxn = 1e6 + 9;
const int N = 6e5 + 123;                                          
const int M = 22;
const int pri = 997;
const int Magic = 2101;

const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};
mt19937 gen(chrono::steady_clock::now().time_since_epoch().count());
 
int rnd (int l, int r) {
	return uniform_int_distribution<int> (l, r)(gen);
}
 
int n, m, k;
int ans[N];
int sum[N];
int cnt[N];
int a[N], b[N], c[N], d[N];
int up[18][N];
int x[N], y[N];
int h[N];
int lca (int a, int b) {
	if (h[a] < h[b]) swap(a, b);
	int dif = h[a] - h[b];
	for (int i = 16; i >= 0 && dif > 0; --i) {
		if (dif >= (1 << i)) {
			a = up[i][a];
			dif -= (1<<i);
		}
	}
	if(a==b) return a;
	for (int i = 16; i >= 0; --i) if (up[i][a] != up[i][b]) {
		a = up[i][a];
		b = up[i][b];
	}
 
	return up[0][a];
}
vector<int> g[N];

void dfs (int v, int par =0) {
	up[0][v] = par;
	for(int i = 1; i < 17; ++i)
		up[i][v] = up[i-1][up[i-1][v]];
	for(auto id : g[v]) {
		int to = (v ^ a[id] ^ b[id]);
		if(to == par) continue;
		h[to] = h[v] + 1;
		dfs(to, v);
	}
}

vector < int > q[N];    
int cur;

void calc (int v, int par = 0) {
	for (auto j : q[v]) {
		int i = j;
		if(j < 0) i *= -1;

		int now = cnt[x[i]] * y[i] + cur - sum[x[i]];
		if(j < 0) now *= -2;
		ans[i] += now;
	}
	for(auto id : g[v]) {
		int to = (v ^ a[id] ^ b[id]);
		if(to == par) continue;
		cnt[c[id]]++;
		sum[c[id]] += d[id];
		cur += d[id];
		calc(to, v);
		cur -= d[id];
		cnt[c[id]] --;
		sum[c[id]] -= d[id];	
	}
}

signed main () {
	SpeedForce;
	setIO();
	
	cin >> n >> m;

	for(int i = 1; i < n; ++i) {
		cin >> a[i] >> b[i] >> c[i] >> d[i];
		g[a[i]].pb(i);
		g[b[i]].pb(i);
	}
	dfs(1);

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

	for (int i = 1; i <= m; ++i) cout << ans[i] << '\n';

	return Accepted;
}

// B...a

Measured memory_bytes: 53724