#include<bits/stdc++.h>
using namespace std;
#define int long long 
inline int read()
{
	int ret=0; char c=getchar();
	while(c<48||c>57)c=getchar();
	while(c>=48 && c<=57)ret=ret*10+c-48,c=getchar();
	return ret;
}

#define N 1050007
#define M 2050007
int su_[M],ee,ff,dd,u,v,cnt,si[N],so[N],di[N],d[N],su[M],fa[N],tp[N],g[N],ans[N],tt,n,uu,cc,c[N<<1][4],tot,a[N],q;

struct wqy {
	int u, v;
	
	wqy(int u_=0, int v_=0){
		u=u_; v=v_;
	}
	
	bool operator < (const wqy & a)const {
		if(u==a.u)return v<a.v;
		return u<a.u;
	}
	
}st[N];

struct node {
	int c, d, u, v, i;
	
	node(int c_=0, int d_=0, int u_=0, int v_=0, int i_=0){
		c=c_,d=d_,u=u_; v=v_; 
		i=i_;  
	}
	
	bool operator < (const node & a)const {
		return c<a.c;
	}
	
}Q[N]; 

set<wqy>s[N];

void ins(int p, int l, int r, int x, int d)
{
	if(l==r){
		su[p]=d;
		return;
	}
	int mi=l+r>>1;
	if(x<=mi)ins(p<<1,l,mi,x,d);else ins((p<<1)|1,mi+1,r,x,d);
	su[p]=su[p<<1]+su[(p<<1)|1];
}

void inss(int p, int l, int r, int x, int d)
{
	su_[p]+=d;
	if(l==r)return;
	int mi=l+r>>1;
	if(x<=mi)inss(p<<1,l,mi,x,d);else inss((p<<1)|1,mi+1,r,x,d);
}


int que(int p, int l, int r, int x, int y)
{
	if(x<=l&&r<=y)return su[p];
	if(x>r||y<l)return 0;
	int mi=l+r>>1;
	return que(p<<1,l,mi,x,y)+que((p<<1)|1,mi+1,r,x,y);
}

int Que(int u, int v)
{
	int ans=0;
	while(tp[u]!=tp[v]){
		if(di[tp[u]]<di[tp[v]])swap(u,v);
		ans+=que(1,1,n,g[tp[u]],g[u]);
		u=fa[tp[u]];
	}
	if(u==v)return ans;
	if(di[u]<di[v])swap(u,v);
	ans+=que(1,1,n,g[v]+1,g[u]);
	return ans;
}

int que2(int p, int l, int r, int x, int y)
{
	if(x<=l&&r<=y)return su_[p];
	if(x>r||y<l)return 0;
	int mi=l+r>>1;
	return que2(p<<1,l,mi,x,y)+que2((p<<1)|1,mi+1,r,x,y);
}

int Que2(int u, int v)
{
	int ans=0;
	while(tp[u]!=tp[v]){
		if(di[tp[u]]<di[tp[v]])swap(u,v);
		ans+=que2(1,1,n,g[tp[u]],g[u]);
		u=fa[tp[u]];
	}
	if(u==v)return ans;
	if(di[u]<di[v])swap(u,v);
	ans+=que2(1,1,n,g[v]+1,g[u]);
	return ans;
}

void dfs(int p, int pr, int dd)
{
	di[p]=dd; fa[p]=pr; si[p]=1;
	for(int o=a[p]; o; o=c[o][1]){
		if(c[o][0]==pr)continue;
		d[c[o][0]]=c[o][3]; 
		dfs(c[o][0],p,dd+1);
		if(si[c[o][0]]>si[so[p]])so[p]=c[o][0];
		si[p]+=si[c[o][0]];
	}
}

void dfs2(int p, int pr, int tp_)
{
	g[p]=++cnt; tp[p]=tp_;
	if(so[p]){
		dfs2(so[p],p,tp_);
	}
	for(int o=a[p]; o; o=c[o][1]){
		u=c[o][0];
		if(u==pr||u==so[p])continue;
		dfs2(u,p,u);
	}
	ins(1,1,n,g[p],d[p]);
}

signed main()
{
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	
	n=read(); q=read();
	for(int i=1;i<n;++i){
		u=read(); v=read(); cc=read(); dd=read(); 
		c[++tot][0]=v; c[tot][1]=a[u]; a[u]=tot; c[tot][2]=cc; c[tot][3]=dd;
		c[++tot][0]=u; c[tot][1]=a[v]; a[v]=tot; c[tot][2]=cc; c[tot][3]=dd;
		s[cc].insert((wqy){u,v});
	} 
	dfs(1,0,1);
	dfs2(1,0,1);
	for(int i=1;i<=q;++i)Q[i].c=read(),Q[i].d=read(),Q[i].u=read(),Q[i].v=read(),Q[i].i=i;
	sort(Q+1,Q+q+1);
	uu=1;
	while(uu<=q){
		cc=Q[uu].c; 
		
//		if(s[cc].empty()){
//			ans[Q[uu].i]=
//		} 
		
		tt=0;
		for(set<wqy>::iterator it=s[cc].begin();it!=s[cc].end();++it){
			u=it->u; v=it->v;
			if(di[u]<di[v])swap(u,v);
			st[++tt]=(wqy){u,d[u]}; 
			ins(1,1,n,g[u],Q[uu].d);
			inss(1,1,n,g[u],1);
		}
		
		ee=Q[uu].d;
		
		do{
			cc=Que(Q[uu].u,Q[uu].v);
			ff=Que2(Q[uu].u,Q[uu].v);
			ans[Q[uu].i]=cc+ff*(Q[uu].d-ee);
			++uu;
		}while(Q[uu].c==Q[uu-1].c);
		
		for(int i=1;i<=tt;++i)ins(1,1,n,g[st[i].u],st[i].v),inss(1,1,n,g[st[i].u],-1);
	}
	
	for(int i=1;i<=q;++i)printf("%lld\n",ans[i]);
}

Measured memory_bytes: 160128