#include <iostream>
#include <string.h>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <queue>

using namespace std;

struct E{
	int to,color;
	long long int colorLen;
};

struct hen{
	int to,color;
	long long int len;
};

struct Q{
	int from,to,color;
	long long int len,len2;
	bool operator<(const Q& q1)const{
		if(from!=q1.from)return from<q1.from;
		if(to!=q1.to)return to<q1.to;
		if(color!=q1.color)return color<q1.color;
		return len<q1.len;
	}
};


long long int colorCount[100003];
long long int lens[100003];
long long int colorLens[100003];

map<int,int> noToP;
map<int,int> noToP2;
set<int> noMemo;
int nos[100003];
vector<hen> g[100003];
vector<Q> topMemo[100003];
vector<E> trapMemo[100003];
vector<E> trapMemo2[100003];
vector<Q> qs;
map<Q,long long int> ansMemo;
set<Q> setQs;


int all;
int no=0;

void f0(int p,int oya){
	for(int i=0;i<g[p].size();i++){
		hen h1=g[p][i];
		if(h1.to==oya)continue;
		f0(h1.to,p);
	}
	noToP[no]=p;
	nos[p]=no;
	no++;
}
void f0b(int p,int oya){
	for(int i=g[p].size()-1;i>=0;i--){
		hen h1=g[p][i];
		if(h1.to==oya)continue;
		f0b(h1.to,p);
	}
	noToP[no]=p;
	nos[p]=no;
	no++;
}
void f1(int p,int oya,long long int len){
	int no3=nos[p];
	noMemo.insert(no3);
	for(int i=0;i<trapMemo[p].size();i++){
		
		E e1=trapMemo[p][i];
		int top=0;
		if(noMemo.find(nos[e1.to])!=noMemo.end()){
			top=e1.to;
			
		}else{
			if(nos[e1.to]<nos[p])continue;
			top=noToP[(*(noMemo.lower_bound(nos[e1.to])))];
			
		}
			//cout<<"p="<<p<<" "<<e1.to<<" "<<nos[e1.to]<<" "<<top<<"\n";
			Q q1;
			q1.from=min(p,e1.to);
			q1.to=max(e1.to,p);
			q1.color=e1.color;
			q1.len2=len-colorLens[e1.color]+colorCount[e1.color]*e1.colorLen;
			q1.len=e1.colorLen;
			//cout<<"p="<<p<<"\n";
			//cout<<"c=("<<len<<" "<<colorLens[e1.color]<<" "<<colorCount[e1.color]<<" "<<e1.colorLen<<"\n";
			//cout<<"a,top="<<top<<"from="<<q1.from<<" to="<<q1.to<<" no="<<nos[q1.to]<<"\n";
			//cout<<"b "<<p<<" "<<nos[p]<<" "<<e1.to<<" "<<nos[e1.to]<<"\n";
			//for(set<int>::iterator it=noMemo.begin();it!=noMemo.end();it++){
			//	cout<<"("<<(*it)<<" "<<noToP[(*it)]<<")";
			//}
			//cout<<"\n";
			topMemo[top].push_back(q1);
	}
	for(int i=0;i<g[p].size();i++){
		hen h1=g[p][i];
		if(h1.to==oya)continue;
		colorCount[h1.color]++;
		colorLens[h1.color]+=h1.len;
		
		f1(h1.to,p,len+h1.len);
		
		colorCount[h1.color]--;
		colorLens[h1.color]-=h1.len;
	}
	for(int i=0;i<topMemo[p].size();i++){
		Q q1=topMemo[p][i];
		//cout<<"?0="<<p<<" "<<q1.from<<" "<<q1.to<<"\n";
		//cout<<"?1="<<q1.len2<<" "<<len<<" "<<colorLens[q1.color]<<" "<<colorCount[q1.color]<<" "<<q1.len<<"\n";
		long long int t3=(q1.len2-(len-colorLens[q1.color]+colorCount[q1.color]*q1.len));
		ansMemo[q1]+=t3;

	}
	noMemo.erase(no3);
	topMemo[p].clear();
}
void f2(int p,int oya,long long int len){
	int no3=nos[p];
	noMemo.insert(no3);
	for(int i=0;i<trapMemo[p].size();i++){
		
		E e1=trapMemo[p][i];
		int top=0;
		//cout<<"p="<<p<<" "<<e1.to<<" "<<nos[e1.to]<<" "<<top<<"\n";
		if(noMemo.find(nos[e1.to])!=noMemo.end()){
			//cout<<"bad";
			continue;
		}else{
			//cout<<"ok";
			if(nos[e1.to]<nos[p])continue;
			top=noToP[(*(noMemo.lower_bound(nos[e1.to])))];
			
		}
			//cout<<"p="<<p<<" "<<e1.to<<" "<<nos[e1.to]<<" "<<top<<"\n";
			Q q1;
			q1.from=min(p,e1.to);
			q1.to=max(e1.to,p);
			q1.color=e1.color;
			q1.len2=len-colorLens[e1.color]+colorCount[e1.color]*e1.colorLen;
			q1.len=e1.colorLen;
			//cout<<"p="<<p<<"\n";
			//cout<<"c=("<<len<<" "<<colorLens[e1.color]<<" "<<colorCount[e1.color]<<" "<<e1.colorLen<<"\n";
			//cout<<"a,top="<<top<<"from="<<q1.from<<" to="<<q1.to<<" no="<<nos[q1.to]<<"\n";
			//cout<<"b "<<p<<" "<<nos[p]<<" "<<e1.to<<" "<<nos[e1.to]<<"\n";
			//for(set<int>::iterator it=noMemo.begin();it!=noMemo.end();it++){
			//	cout<<"("<<(*it)<<" "<<noToP[(*it)]<<")";
			//}
			//cout<<"\n";
			topMemo[top].push_back(q1);
	}
	for(int i=g[p].size()-1;i>=0;i--){
		hen h1=g[p][i];
		if(h1.to==oya)continue;
		colorCount[h1.color]++;
		colorLens[h1.color]+=h1.len;
		
		f2(h1.to,p,len+h1.len);
		
		colorCount[h1.color]--;
		colorLens[h1.color]-=h1.len;
	}
	for(int i=0;i<topMemo[p].size();i++){
		Q q1=topMemo[p][i];
		//cout<<"?0="<<p<<" "<<q1.from<<" "<<q1.to<<"\n";
		//cout<<"?1="<<q1.len2<<" "<<len<<" "<<colorLens[q1.color]<<" "<<colorCount[q1.color]<<" "<<q1.len<<"\n";
		long long int t3=(q1.len2-(len-colorLens[q1.color]+colorCount[q1.color]*q1.len));
		ansMemo[q1]+=t3;

	}
	noMemo.erase(no3);
}

void reset(){
	memset(colorCount,0,sizeof(colorCount));
	memset(lens,0,sizeof(lens));
	memset(colorLens,0,sizeof(colorLens));
	no=0;
	noToP.clear();
	noMemo.clear();
}

int main() {
	// your code goes here
	int n,q;
	cin>>n>>q;
	all=n+3;
	for(int i=0;i<n-1;i++){
		int from,to,color;
		long long int len;
		cin>>from>>to>>color>>len;
		hen h1;
		h1.to=to;
		h1.color=color;
		h1.len=len;
		g[from].push_back(h1);
		h1.to=from;
		g[to].push_back(h1);
	}
	for(int i=0;i<q;i++){
		int color,len,from,to;
		cin>>color>>len>>from>>to;
		Q q1;
		q1.from=min(from,to);
		q1.to=max(from,to);
		q1.color=color;
		q1.len=len;
		qs.push_back(q1);
		setQs.insert(q1);

	}
	for(set<Q>::iterator it=setQs.begin();it!=setQs.end();it++){
		Q q1=(*it);
		E e1;
		e1.color=q1.color;
		e1.colorLen=q1.len;
		e1.to=q1.to;
		trapMemo[q1.from].push_back(e1);
		e1.to=q1.from;
		trapMemo[q1.to].push_back(e1);
	}
	
	reset();
	f0(1,0);
	f1(1,0,0);
	reset();
	f0b(1,0);
	//for(int i=1;i<=n;i++)cout<<" ("<<i<<","<<nos[i]<<")";
	f2(1,0,0);
	//for(map<Q,long long int>::iterator it=ansMemo.begin();it!=ansMemo.end();it++){
	//	Q q=(*it).first;
	//	cout<<"q="<<q.from<<" "<<q.to<<" "<<q.len<<" ans="; 
	//	cout<<(*it).second<<"\n";
	//}
	for(int i=0;i<qs.size();i++){
		//cout<<"t="<<qs[i].from<<" "<<qs[i].to<<" "<<ansMemo[qs[i]]<<"\n";
		cout<<ansMemo[qs[i]]<<"\n";
	}
	return 0;
}

Measured memory_bytes: 64620