/*
Though leaves are many , the root is one.
Through all the lying days of my youth
I swayed my leaves and flowers in the sun.
Now I may wither into the truth.
	  	  	- William Butler Yeats
*/
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//#pragma GCC target("avx,tune=native")
#include<bits/stdc++.h>
#pragma comment("-Wl,--stack=1024000000")
//#include<ext/pb_ds/assoc_container.hpp>
using namespace std;
//using namespace __gnu_pbds;
const int inf=0x3f3f3f3f;
const double eps=1e-6;
const int mod=1000000007;
typedef long long ll;
#ifndef LOCAL
#define cerr if(0)cout
#define eprintf(...) 0
#else
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#endif
inline string getstr(string &s,int l,int r){string ret="";for(int i=l;i<=r;i++)ret.push_back(s[i]);return ret;}
int modpow(int x,int y,int md=mod){int ret=1;do{if(y&1)ret=(ll)ret*x%md;x=(ll)x*x%md;}while(y>>=1);return ret;}
int n,q;
struct ask{
	int mul,a,b,id;
	ask(int m,int aa,int bb,int i){mul=m;a=aa;b=bb;id=i;}
};
vector<ask>qry[100005];
vector<pair<int,int> >g[100005];
pair<int,int>e[100005];
struct SGT{
	#define SIZE 131072
	int f[SIZE<<1]={},l,r;
	void add(int x,int v){
		x+=SIZE;f[x]+=v;
		while(x!=1){
			x>>=1;
			f[x]=f[x<<1]+f[x<<1|1];
		}
	}
	int sum(int L,int R,int k){
		if(R<l||r<L)return 0;
		if(l<=L&&R<=r){
			return f[k];
		}
		return sum(L,(L+R)/2,k<<1)+sum((L+R)/2+1,R,k<<1|1);
	}
	int query(int _l,int _r){
		l=_l;r=_r;return sum(0,SIZE-1,1);
	}
}sum,cnt,dist;
int sz[100005],wson[100005],top[100005],dep[100005],par[100005],id[100005],ans[100005];
void dfs(int x,int p){
	sz[x]=1;int best=0;wson[x]=-1;
	for(auto c:g[x]){
		int to=c.first;
		if(to!=p){
			dep[to]=dep[x]+1;dfs(to,x);sz[x]+=sz[to];
			if(sz[to]>best)wson[x]=to,best=sz[to];
		}else{
			par[x]=p;id[x]=c.second;
		}
	}
}
int order[100005],pos[100005],ordn;
void push(int x,int p,int v){
	top[x]=v;order[++ordn]=x;pos[x]=ordn;
	if(~wson[x])push(wson[x],x,v);
	for(auto c:g[x]){
		int to=c.first;
		if(to!=p&&to!=wson[x])push(to,x,to);
	}
}
vector<pair<int,int> >got[100005];
int get(int x,int y,SGT&T,int mul){
	int ret=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]){
			swap(x,y);
		}
		ret+=T.query(pos[top[x]],pos[x]);
		x=par[top[x]];
	}
	if(dep[x]<dep[y])swap(x,y);
	ret+=T.query(pos[y]+1,pos[x]);
	return ret*mul;
}
signed main(){
	cin>>n>>q;
	for(int i=1;i<=n-1;i++){
		int x,y,c,d;cin>>x>>y>>c>>d;
		g[x].push_back(make_pair(y,i));
		g[y].push_back(make_pair(x,i));
		e[i]=make_pair(c,d);
		got[c].push_back(make_pair(x,y));
	}
	for(int i=1;i<=q;i++){
		int x,y,a,b;
		cin>>x>>y>>a>>b;
		qry[x].push_back(ask(y,a,b,i));
	}
	dep[1]=1;dfs(1,-1);
	push(1,-1,1);
	for(int i=2;i<=n;i++)dist.add(pos[i],e[id[i]].second);
	for(int i=1;i<=n;i++){
		for(auto p:got[i]){
			int x=p.first,y=p.second;
			if(par[y]==x)swap(x,y);
			cnt.add(pos[x],1);
			sum.add(pos[x],e[id[x]].second);
		}
		for(auto Q:qry[i]){
			cerr<<Q.id<<" "<<get(Q.a,Q.b,dist,1)<<" "<<get(Q.a,Q.b,cnt,Q.mul)<<" "<<get(Q.a,Q.b,sum,1)<<endl;
			ans[Q.id]=get(Q.a,Q.b,dist,1)+get(Q.a,Q.b,cnt,Q.mul)-get(Q.a,Q.b,sum,1);
		}
		for(auto p:got[i]){
			int x=p.first,y=p.second;
			if(par[y]==x)swap(x,y);
			cnt.add(pos[x],-1);
			sum.add(pos[x],-e[id[x]].second);
		}
	}
	for(int i=1;i<=q;i++)cout<<ans[i]<<endl;
	return 0;
}

Measured memory_bytes: 27892