#include<bits/stdc++.h>

#define FOR(x,y,z) for(int x=y,x##_=z;x<=x##_;++x)
#define DOR(x,y,z) for(int x=y,x##_=z;x>=x##_;--x)
#define FOR_(x,y,z,s) for(int x=y,x##_=z;x<=x##_;x+=s)
#define FOR__(x,y,z) for(int x=y,x##_=z;x<=x##_;x<<=1)
#define EOR(x,y) for(int x##_=head[x],y=edge[x##_].e;x##_;y=edge[x##_=edge[x##_].to].e)
#define EGOR(x,y,z) for(int x##_=head[x],y=edge[x##_].e,z=edge[x##_].c;x##_;y=edge[x##_=edge[x##_].to].e,z=edge[x##_].c)

#define clr(x,y) memset(x,y,sizeof(x))
#define szf(x) sizeof(x)
#define min3(x,y,z) min(min(x,y),z)
#define max3(x,y,z) max(max(x,y),z)

#define read2(x,y) read(x),read(y)
#define read3(x,y,z) read(x),read(y),read(z)
#define read4(x,y,z,w) read3(x,y,z),read(w)
#define reads(str) sf("%s",str)

#define ts (*this)
#define sf scanf
#define pf printf

#define ll long long
#define ull unsigned long long
#define db double
#define ct clock_t
#define ck() clock()
#define rd rand()
#define rmx RAND_MAX
#define RD T*(rd*2-rmx)


using namespace std;

template<class T>bool tomin(T &x,T y){return x>y?x=y,1:0;}
template<class T>bool tomax(T &x,T y){return x<y?x=y,1:0;}
template<class T>void read(T &x){
	char c;
	x=0;
	int f=1;
	while(c=getchar(),c<'0'||c>'9')if(c=='-')f=-1;
	do x=(x<<3)+(x<<1)+(c^48);
	while(c=getchar(),c>='0'&&c<='9');
	x*=f;
}

const db Pi=acos(-1);
const int maxn=1e5+5;
int n,m,Q;
struct node{
	int id,t,c,d;
};
vector<node>q[maxn];
struct Edge{
	int e,c,d,to;
}edge[maxn<<1];
int head[maxn],tot;
void Add(int x,int y,int c,int d){
	edge[++tot]=(Edge){y,c,d,head[x]};
	head[x]=tot;
}
int fa[maxn],son[maxn],sz[maxn],top[maxn],dep[maxn];
void dfs(int u,int f){
	dep[u]=dep[f]+1;
	fa[u]=f;
	son[u]=0;
	sz[u]=1;
	EOR(u,v)if(v!=f){
		dfs(v,u);
		sz[u]+=sz[v];
		if(sz[son[u]]<sz[v])son[u]=v;
	}
}
void dfs_top(int u,int tp){
	top[u]=tp;
	EOR(u,v)if(v!=fa[u])
		dfs_top(v,v==son[u]?tp:v);
}
int LCA(int x,int y){
	while(top[x]!=top[y]){
		if(dep[top[x]]>dep[top[y]])x=fa[top[x]];
		else y=fa[top[y]];
	}return dep[x]>dep[y]?y:x;
}
namespace YD{
	#define lson ls[od],ls[pr],L,mid
	#define rson rs[od],rs[pr],mid+1,R
	const int maxm=maxn*20;
	int ls[maxm],rs[maxm],rt[maxm];
	int num[maxm];
	int sum[maxm];
	int tot;
	void Create(int od,int &pr){
		pr=++tot;
		ls[pr]=ls[od];
		rs[pr]=rs[od];
		sum[pr]=sum[od];
		num[pr]=num[od];
	}
	void update(int od,int &pr,int L,int R,int c,int d){
		Create(od,pr);
		sum[pr]+=d;
		num[pr]++;
		if(L==R)return;
		int mid=L+R>>1;
		if(c<=mid)update(lson,c,d);
		else update(rson,c,d);
	}
	int query_sum(int od,int pr,int L,int R,int c){
		if(L==R)return sum[pr]-sum[od];
		int mid=L+R>>1;
		if(c<=mid)return query_sum(lson,c);
		return query_sum(rson,c);
	}
	int query_num(int od,int pr,int L,int R,int c){
		if(L==R)return num[pr]-num[od];
		int mid=L+R>>1;
		if(c<=mid)return query_num(lson,c);
		return query_num(rson,c);
	}
	void Add(int x,int c,int d){
		update(rt[x-1],rt[x],1,n-1,c,d);
	}
	int query(int x,int y,int c,int d){
		// pf("query %d %d %d %d %d %d\n",x,y,c,d,sum[rt[y]],sum[rt[x]]);
		// return sum[rt[y]]-sum[rt[x]];
		return sum[rt[y]]-sum[rt[x]]-query_sum(rt[x],rt[y],1,n-1,c)+d*query_num(rt[x],rt[y],1,n-1,c);
	}
}
int ans[maxn];
void solve(int u,int f){
	FOR(i,0,q[u].size()-1)
		ans[q[u][i].id]+=YD::query(dep[q[u][i].t],dep[u],q[u][i].c,q[u][i].d);
	EOR(u,v)if(v!=f){
		int c=edge[u_].c,d=edge[u_].d;
		YD::Add(dep[v],c,d);
		solve(v,u);
	}
}
int main(){
	srand(time(NULL));
	read2(n,Q);
	int x,y,c,d;
	FOR(i,2,n){
		read4(x,y,c,d);
		Add(x,y,c,d);
		Add(y,x,c,d);
	}
	dep[0]=-1;
	dfs(1,0);
	dfs_top(1,1);
	FOR(i,1,Q){
		read4(c,d,x,y);
		int lca=LCA(x,y);
		// pf("LCA[%d,%d]=%d\n",x,y,lca);
		if(x!=lca)q[x].push_back((node){i,lca,c,d});
		if(y!=lca)q[y].push_back((node){i,lca,c,d});
	}
	solve(1,0);
	FOR(i,1,Q)pf("%d\n",ans[i]);
	return 0;
}


Measured memory_bytes: 51456