//Coded by tzc_wk
/*
Êý¾Ý²»Çå¿Õ£¬±¬ÁãÁ½ÐÐÀá¡£
¶à²â²»¶ÁÍê£¬±¬ÁãÁ½ÐÐÀá¡£
±ß½ç²»ÌØÅÐ£¬±¬ÁãÁ½ÐÐÀá¡£
Ì°ÐÄ²»Ö¤Ã÷£¬±¬ÁãÁ½ÐÐÀá¡£
D P Ë³Ðò´í£¬±¬ÁãÁ½ÐÐÀá¡£
´óÐ¡ÉÙµÈºÅ£¬±¬ÁãÁ½ÐÐÀá¡£
±äÁ¿²»Í³Ò»£¬±¬ÁãÁ½ÐÐÀá¡£
Ô½½ç²»ÅÐ¶Ï£¬±¬ÁãÁ½ÐÐÀá¡£
µ÷ÊÔ²»×¢ÊÍ£¬±¬ÁãÁ½ÐÐÀá¡£
Òç³ö²» l l£¬±¬ÁãÁ½ÐÐÀá¡£
*/
#include <bits/stdc++.h>
using namespace std;
#define fi			first
#define se			second
#define fz(i,a,b)	for(int i=a;i<=b;i++)
#define fd(i,a,b)	for(int i=a;i>=b;i--)
#define foreach(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define all(a)		a.begin(),a.end()
#define giveup(...) return printf(__VA_ARGS__),0;
#define fill0(a)	memset(a,0,sizeof(a))
#define fill1(a)	memset(a,-1,sizeof(a))
#define fillbig(a)	memset(a,0x3f,sizeof(a))
#define fillsmall(a) memset(a,0xcf,sizeof(a))
#define mask(a)		(1ll<<(a))
#define maskx(a,x)	((a)<<(x))
#define _bit(a,x)	(((a)>>(x))&1)
#define _sz(a)		((int)(a).size())
#define filei(a)	freopen(a,"r",stdin);
#define fileo(a)	freopen(a,"w",stdout);
#define fileio(a) 	freopen(a".in","r",stdin);freopen(a".out","w",stdout)
#define eprintf(...) fprintf(stderr,__VA_ARGS__)
#define put(x)		putchar(x)
#define eoln        put('\n')
#define space		put(' ')
#define y1			y_chenxiaoyan_1
#define y0			y_chenxiaoyan_0
typedef pair<int,int> pii;
inline int read(){
	int x=0,neg=1;char c=getchar();
	while(!isdigit(c)){
		if(c=='-')	neg=-1;
		c=getchar();
	}
	while(isdigit(c))	x=x*10+c-'0',c=getchar();
	return x*neg;
}
inline void print(int x){
	if(x<0){
		putchar('-');
		print(abs(x));
		return;
	}
	if(x<=9)	putchar(x+'0');
	else{
		print(x/10);
		putchar(x%10+'0');
	}
}
inline int qpow(int x,int e,int _MOD){
	int ans=1;
	while(e){
		if(e&1)	ans=ans*x%_MOD;
		x=x*x%_MOD;
		e>>=1;
	}
	return ans;
}
int n=read(),m=read();
struct edge{
	int u,v,c,d,id;
} e[100005];
struct query{
	int u,v,x,y;
} q[100005];
vector<edge> g[100005];
vector<int> es[100005];
vector<int> qs[100005];
int fa[100005],sz[100005],dfn[100005],dep[100005],wson[100005],id[100005],idx=0;
int eid[100005],w[100005],top[100005];
inline void dfs1(int x,int prev){
	fa[x]=prev;sz[x]=1;
	for(int i=0;i<g[x].size();i++){
		edge E=g[x][i];
		int y=E.v;
		if(y==prev)	continue;
		eid[E.id]=y;w[y]=E.d;
		dep[y]=dep[x]+1;
		dfs1(y,x);
		sz[x]+=sz[y];
		if(sz[y]>sz[wson[x]])	wson[x]=y;
	}
}
inline void dfs2(int x,int tp){
	top[x]=tp;
	dfn[x]=++idx;
	id[idx]=x;
	if(wson[x])	dfs2(wson[x],tp);
	for(int i=0;i<g[x].size();i++){
		edge e=g[x][i];
		int y=e.v;
		if(y==fa[x]||y==wson[x])	continue;
		dfs2(y,y);
	}
}
struct SegTree{
	struct node{
		int k,l,r,val1,val2;
	} s[100005<<2];
	inline void build(int k,int l,int r){
		s[k].l=l;s[k].r=r;
		if(l==r){
			s[k].val1=w[id[l]];
//			cout<<"setup "<<l<<" "<<w[id[l]]<<endl;
			s[k].val2=0;
			return;
		}
		int mid=(l+r)>>1;
		build(k<<1,l,mid);
		build(k<<1|1,mid+1,r);
		s[k].val1=s[k<<1].val1+s[k<<1|1].val1;
	}
	inline void modify_1(int k,int ind,int x){
		if(s[k].l==s[k].r){
//			cout<<"modify_1 "<<s[k].l<<" "<<x<<endl;
			s[k].val1=x;
			return;
		}
		int mid=(s[k].l+s[k].r)>>1;
		if(ind<=mid)	modify_1(k<<1,ind,x);
		else			modify_1(k<<1|1,ind,x);
		s[k].val1=s[k<<1].val1+s[k<<1|1].val1;
	}
	inline void modify_2(int k,int ind,int x){
		if(s[k].l==s[k].r){
//			cout<<"modify_2 "<<s[k].l<<" "<<x<<endl;
			s[k].val2=x;
			return;
		}
		int mid=(s[k].l+s[k].r)>>1;
		if(ind<=mid)	modify_2(k<<1,ind,x);
		else			modify_2(k<<1|1,ind,x);
		s[k].val2=s[k<<1].val2+s[k<<1|1].val2;
	}
	inline int query_1(int k,int l,int r){
		if(l>r)	return 0;
		if(l<=s[k].l&&s[k].r<=r){
			return s[k].val1;
		}
		int mid=(s[k].l+s[k].r)>>1;
		if(r<=mid)		return query_1(k<<1,l,r);
		else if(l>mid)	return query_1(k<<1|1,l,r);
		else			return query_1(k<<1,l,mid)+query_1(k<<1|1,mid+1,r);
	}
	inline int query_2(int k,int l,int r){
		if(l>r)	return 0;
		if(l<=s[k].l&&s[k].r<=r){
			return s[k].val2;
		}
		int mid=(s[k].l+s[k].r)>>1;
		if(r<=mid)		return query_2(k<<1,l,r);
		else if(l>mid)	return query_2(k<<1|1,l,r);
		else			return query_2(k<<1,l,mid)+query_2(k<<1|1,mid+1,r);
	}
} st;
inline int query(int u,int v,int x){
//	cout<<u<<" "<<v<<" "<<x<<endl;
	if(dep[u]<dep[v])	swap(u,v);
	int ans=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])	swap(u,v);
//		cout<<"query "<<dfn[top[u]]<<" "<<dfn[u]<<endl;
		ans+=st.query_1(1,dfn[top[u]],dfn[u]);
		ans+=x*st.query_2(1,dfn[top[u]],dfn[u]);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v])	swap(u,v);
	if(u!=v){
//		cout<<"query "<<dfn[v]+1<<" "<<dfn[u]<<endl;
		ans+=st.query_1(1,dfn[v]+1,dfn[u]);
		ans+=x*st.query_2(1,dfn[v]+1,dfn[u]);
	}
	return ans;
}
int q_ans[100005];
signed main(){
	fz(i,1,n-1){
		e[i].u=read();e[i].v=read();e[i].c=read();e[i].d=read();
		e[i].id=i;
		g[e[i].u].push_back({e[i].u,e[i].v,e[i].c,e[i].d,i});
		g[e[i].v].push_back({e[i].v,e[i].u,e[i].c,e[i].d,i});
		es[e[i].c].push_back(i);
	}
	fz(i,1,m){
		q[i].x=read();q[i].y=read();q[i].u=read();q[i].v=read();
		qs[q[i].x].push_back(i);
	}
	dfs1(1,0);dfs2(1,1);
//	fz(i,1,n)	cout<<w[id[i]]<<endl;
	st.build(1,1,n);
	fz(i,1,n-1){
		foreach(it,es[i]){
			int j=eid[*it];
//			cout<<i<<" "<<j<<endl;
			st.modify_1(1,dfn[j],0);
			st.modify_2(1,dfn[j],1);
		}
//		cout<<i<<endl;
		foreach(it,qs[i]){
			int j=*it;
			q_ans[j]=query(q[j].u,q[j].v,q[j].y);
		}
		foreach(it,es[i]){
			int j=eid[*it];
			st.modify_1(1,dfn[j],e[*it].d);
			st.modify_2(1,dfn[j],0);
		}
	}
	fz(i,1,m)	cout<<q_ans[i]<<endl;
	return 0;
}

Measured memory_bytes: 50556