#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;

#define X first
#define Y second

//#include <boost/unordered_map.hpp>
//using namespace boost;

/*
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
rbtree T;
*/

using i32 = int;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;
//using i128 = __int128_t;
//using u128 = __uint128_t;
using i128 = i64;
using u128 = u64;

ll power(ll a, ll b, ll p)
{
	if (!b) return 1;
	ll t = power(a, b/2, p);
	t = t*t%p;
	if (b&1) t = t*a%p;
	return t;
}

ll exgcd(ll a, ll b, ll &x, ll &y)
{
	if (b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	ll px, py;
	ll d = exgcd(b, a%b, px, py);
	x = py;
	y = px-a/b*py;
	return d;
}

template<class T>
inline void freshmin(T &a, const T &b)
{
	if (a > b) a = b;
}

template<class T>
inline void freshmax(T &a, const T &b)
{
	if (a < b) a = b;
}

//#define getchar getchar_unlocked
//#define putchar putchar_unlocked

int inp() {
	int x = 0, f = 0; char ch;
	for(ch = getchar(); !isdigit(ch); ch = getchar())
		if(ch == '-') f = 1;
	for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
	return f ? -x : x;
}

ll inp_ll() {
	ll x = 0; int f = 0; char ch;
	for(ch = getchar(); !isdigit(ch); ch = getchar())
		if(ch == '-') f = 1;
	for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
	return f ? -x : x;
}

template<class T>
bool read(T &x)
{
	x = 0;
	char ch = getchar();
	if (ch == EOF) return 0;
	for(; !isdigit(ch); )
	{
		ch = getchar();
		if (ch == EOF) return 0;
	}
	for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
	return 1;
}

template<class T>
void write(T x)
{
	static char s[22];
	static char *it = s+20;
	static char *end = s+20;
	if (!x)
		*-- it = '0';
	while (x)
	{
		*-- it = x%10+'0';
		x /= 10;
	}
	for (; it < end; ++ it)
		putchar(*it);
}

template<class T>
void writeln(T x)
{
	write(x);
	putchar('\n');
}

const int MOD = 1000000007;
const int INF = 100000000;
const int MAXN = 200010;
const int MAXV = 500510;
const int MAXK = 17;
const f80 eps = 1e-10;
const f64 alpha = 0.75;

int n, k;
vector<vector<int> > v[MAXN], ask[MAXN];

int times, X[MAXN], Y[MAXN];
int pre[MAXN][MAXK];
int dis[MAXN], depth[MAXN];
vector<int> color[MAXN];

void dfs(int x, int p)
{
	X[x] = ++ times;
	for (auto e : v[x])
	{
		int y = e[0];
		int c = e[1];
		int d = e[2];
		if (y == p) continue;
		pre[y][0] = x;
		dis[y] = dis[x]+d;
		depth[y] = depth[x]+1;
		color[c].push_back(y);
		dfs(y, x);
	}
	Y[x] = times;
}

int getLCA(int x, int y)
{
	if (depth[x] < depth[y]) swap(x, y);
	for (int k = MAXK-1; k >= 0; -- k)
		if (depth[x]-depth[y] >= 1<<k)
			x = pre[x][k];
	if (x == y) return x;
	for (int k = MAXK-1; k >= 0; -- k)
		if (pre[x][k] != pre[y][k])
		{
			x = pre[x][k];
			y = pre[y][k];
		}
	return pre[x][0];
}

int a[MAXN], b[MAXN];

void add(int *a, int x, int p)
{
	for (; x <= n; x += x&-x)
		a[x] += p;
}

void add(int *a, int x, int y, int p)
{
	add(a, x, p);
	add(a, y+1, -p);
}

int get(int *a, int x)
{
	int p = 0;
	for (; x; x -= x&-x)
		p += a[x];
	return p;
}

int ans[MAXN];

int main()
{
	
	int q;
	cin >> n >> q;
	for (int i = 1; i < n; ++ i)
	{
		int x, y, c, d;
		cin >> x >> y >> c >> d;
		v[x].push_back({y, c, d});
		v[y].push_back({x, c, d});
	}
	for (int i = 1; i <= q; ++ i)
	{
		int x, y, u, v;
		cin >> x >> y >> u >> v;
		ask[x].push_back({y, u, v, i});
	}
	dfs(1, 0);
	
	for (int k = 1; k < MAXK; ++ k)
		for (int i = 1; i <= n; ++ i)
			pre[i][k] = pre[pre[i][k-1]][k-1];
	
	for (int i = 1; i < n; ++ i)
	{
		for (auto x : color[i])
		{
			add(a, X[x], Y[x], 1);
			add(b, X[x], Y[x], dis[x]-dis[pre[x][0]]);
		}
		
		for (auto e : ask[i])
		{
			int w = e[0];
			int x = e[1];
			int y = e[2];
			int id = e[3];
			int u = getLCA(x, y);
			int ax = get(a, X[x]);
			int ay = get(a, X[y]);
			int au = get(a, X[u]);
			int bx = get(b, X[x]);
			int by = get(b, X[y]);
			int bu = get(b, X[u]);
			ans[id] = dis[x]+dis[y]-2*dis[u]+(ax+ay-2*au)*w-(bx+by-2*bu);
		}
		
		for (auto x : color[i])
		{
			add(a, X[x], Y[x], -1);
			add(b, X[x], Y[x], -(dis[x]-dis[pre[x][0]]));
		}
	}
	
	for (int i = 1; i <= q; ++ i)
		printf("%d\n", ans[i]);
	
	return 0;
}


Measured memory_bytes: 59316