#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<utility>
#include<set>
#include<stack>
#include<list>
#include<deque>
#include<bitset>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<climits>
#include<cmath>
#include<cctype>


#define pb push_back
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ren(i,a,b) for(int i=a;i>=b;i--)
#define ff first
#define ss second
#define pll pair<long long int,long long int>
#define pii pair<int,int>
#define vll vector<long long int>
#define vii vector<int>
#define gi(n) scanf("%d",&n)
#define gll(n) scanf("%lld",&n)
#define gstr(n) scanf("%s",n)
#define gl(n) cin >> n
#define oi(n) printf("%d",n)
#define oll(n) printf("%lld",n)
#define ostr(n) printf("%s",n)
#define ol(n) cout << n
#define os cout<<" "
#define on cout<<"\n"
#define o2(a,b) cout<<a<<" "<<b
#define all(n) n.begin(),n.end()
#define present(s,x) (s.find(x) != s.end())
#define cpresent(s,x) (find(all(s),x) != s.end())
#define tr(container, it) for(__typeof(container.begin()) it = container.begin(); it != container.end(); it++)
using namespace std;

typedef unsigned long long int ull;
typedef long long int ll;
typedef long double ld;
typedef vector<vector<ll> > mat;

const int N= 200005;
int n,q;

struct node
{
	ll count,sum;
	node *left, *right;

	node(ll sum, ll count, node *left, node *right):
		sum(sum), count(count), left(left), right(right) {}

	node* insert(int l, int r, int w,ll val);
};

node *null = new node(0,0, NULL, NULL); //see line 135

node * node::insert(int l, int r, int w,ll val)
{

	// With in the range, we need a new node
	if(l == r)
	{
		return new node(this->sum+val, this->count+1, null, null);
	}

	int m = (l+r)>>1;

	if(w<=m)
	return new node(this->sum+val,this->count+1, this->left->insert(l, m, w, val), this->right);
	return new node(this->sum+val,this->count+1, this->left, this->right->insert(m+1, r, w,val));

}

pll query(node *x,int l,int r,int w)
{
	if(l==r)return mp(x->sum, x->count);
	int mid=(l+r)/2;
	if(w<=mid)return query(x->left,l,mid,w);
	return query(x->right,mid+1,r,w);
}

node *root[N];

vector<pair<int,pll> > v[N];

ll dis[N],par[25][N],l[N];

void dfs(int at,int p=0,int h=0)
{
	l[at]=h;
	par[0][at]=p;
	rep(i,1,24)par[i][at]=par[i-1][par[i-1][at]];
	tr(v[at],it)
	{
		int to=it->ff;
		ll col=(it->ss).ff;
		ll cst=(it->ss).ss;
		if(to==p)continue;
		root[to]=root[at]->insert(0,n,col,cst);
		dis[to]=dis[at]+cst;
		dfs(to,at,h+1);
	}
}

int lca(int u, int v)
{
	if(l[u] < l[v])
		return lca(v, u);

	int diff = l[u] - l[v];

	rep(i,0,24)
		if((diff>>i) & 1)
			u = par[i][u];

	if(u != v)
	{
		ren(i, 24, 0)
			if(par[i][u] != par[i][v])
			{
				u = par[i][u];
				v = par[i][v];
			}
		u = par[0][u];
	}

	return u;
}


int main()
{ios_base::sync_with_stdio(false);
cin.tie(0);
null->left=null;
null->right=null;
root[0]=root[1]=null;

cin>>n>>q;
rep(i,1,n-1)
{
	int x,y,a,b;
	cin>>x>>y>>a>>b;
	v[x].pb(mp(y,mp(a,b)));
	v[y].pb(mp(x,mp(a,b)));
}

dfs(1);

while(q--)
{
	ll x,y,u,v;
	cin>>x>>y>>u>>v;
	ll lc=lca(u,v);
	ll ans=dis[u]+dis[v]-2*dis[lc];
	pll p1=query(root[u],0,n,x);
	ans+=p1.ss*y-p1.ff;
	p1=query(root[v],0,n,x);
	ans+=p1.ss*y-p1.ff;
	p1=query(root[lc],0,n,x);
	ans-=2*(p1.ss*y-p1.ff);
	ol(ans);on;
}

return 0;
}



Measured memory_bytes: 143616