#include <bits/stdc++.h>
#define MOD 1000000007LL
const int B=300;
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> PP;

struct lcatree{
	static const int MAX_LOG=20;
	static const int MAX=100005;
	vector<int> G[MAX];
	int root;

	int parent[MAX_LOG][MAX];
	int depth[MAX];
	void dfs(int v,int p,int d){
		parent[0][v]=p;
		depth[v]=d;
		for(int i=0;i<G[v].size();i++){
			if(G[v][i]!=p)dfs(G[v][i],v,d+1);
		}
	}

	void init(int V){
		dfs(root,-1,0);
		for(int k=0;k+1<MAX_LOG;k++){
			for(int v=0;v<V;v++){
				if(parent[k][v]<0)parent[k+1][v]=-1;
				else parent[k+1][v]=parent[k][parent[k][v]];
			}
		}
	}
	int lca(int u,int v){
		if(depth[u]>depth[v])swap(u,v);
		for(int k=0;k<MAX_LOG;k++){
			if((depth[v]-depth[u])>>k & 1){
				v=parent[k][v];
			}
		}
		if(u==v)return u;
		for(int k=MAX_LOG-1;k>=0;k--){
			if(parent[k][u]!=parent[k][v]){
				u=parent[k][u];
				v=parent[k][v];
			}
		}
		return parent[0][u];
	}
};

struct query{
	int x,y,u,v,id;
	query(){}
	query(int xx,int yy,int uu,int vv,int iid){
		x=xx;
		y=yy;
		u=uu;
		v=vv;
		id=iid;
	}

	bool operator<(const query &q)const{
		if((x/B)!=(q.x/B))return x<q.x;
		if(y==q.y)return id<q.id;
		return y<q.y;
	}
};

lcatree lc;

int n,q;
vector<PP> G[100005];
int a[100005],b[100005],c[100005],d[100005];
ll cnt[200005];
ll val[200005];
int cnt2[200005];
int st[200005],en[200005];
int sz;
ll sum;
ll ans[200005];
vector<PP> vec;
query que[200005];
int sz2=0;


void dfs(int v,int p){
	st[v]=sz++;
	for(int i=0;i<G[v].size();i++){
		if(G[v][i].first!=p){
			int tsz=sz2++;
			vec.push_back(PP(tsz,G[v][i].second));
			dfs(G[v][i].first,v);
			vec.push_back(PP(tsz,G[v][i].second));
		}
	}
	en[v]=sz++;
}

void change(int v){
	if(cnt2[vec[v].first]==1){
		cnt[vec[v].second.first]--;
		val[vec[v].second.first]-=vec[v].second.second;
		sum-=vec[v].second.second;
	}else{
		cnt[vec[v].second.first]++;
		val[vec[v].second.first]+=vec[v].second.second;
		sum+=vec[v].second.second;
	}
	cnt2[vec[v].first]=1-cnt2[vec[v].first];
}

int main(void){
	scanf("%d%d",&n,&q);
	for(int i=0;i<n-1;i++){
		int a,b,c,d;
		scanf("%d%d%d%d",&a,&b,&c,&d);
		a--;
		b--;
		c--;
		G[a].push_back(PP(b,P(c,d)));
		G[b].push_back(PP(a,P(c,d)));
		lc.G[a].push_back(b);
		lc.G[b].push_back(a);
	}
	vec.push_back(PP(100004,P(100004,0)));
	dfs(0,-1);
	lc.init(n);
	for(int i=0;i<q;i++){
		int x,y,u,v;
		scanf("%d%d%d%d",&u,&v,&x,&y);
		x--;
		y--;
		u--;
		int pa=lc.lca(x,y);
		if(pa==x){
			assert(st[x]<st[y]);
			que[i]=query(st[x]+1,st[y]+1,u,v,i);
		}else if(pa==y){
			assert(st[y]<st[x]);
			que[i]=query(st[y]+1,st[x]+1,u,v,i);
		}else{
			if(st[x]>st[y])swap(x,y);
			assert(en[x]<st[y]);
			que[i]=query(en[x],st[y]+1,u,v,i);
		}
	}
	sort(que,que+q);
	int lb=0,rb=0;
	sum=0;
	for(int i=0;i<n;i++){
		//printf("st=%d en=%d\n",st[i],en[i]);
	}
	for(int i=0;i<vec.size();i++){
		//printf("vec=%d %d %d\n",vec[i].first,vec[i].second.first,vec[i].second.second);
	}
	for(int i=0;i<q;i++){
		while(lb>que[i].x){
			lb--;
			change(lb);
		}
		while(rb<que[i].y){
			change(rb);
			rb++;
		}
		while(lb<que[i].x){
			change(lb);
			lb++;
		}
		while(rb>que[i].y){
			rb--;
			change(rb);
		}
		/*
		printf("query%d %d %d\n",lb,rb,que[i].id);
		for(int i=0;i<n;i++){
			printf("%d ",cnt[i]);
		}
		printf("\n");
		for(int i=0;i<n;i++){
			printf("%d ",val[i]);
		}
		printf("\n");
		*/
		ll tmp=sum-val[que[i].u];
		tmp+=(ll)cnt[que[i].u]*que[i].v;
		ans[que[i].id]=tmp;
	}
	for(int i=0;i<q;i++){
		printf("%lld\n",ans[i]);
	}
	return 0;
}


Measured memory_bytes: 41328