#include <bits/stdc++.h>
using namespace std;
#define modulo 1000000007
#define mod(mod_x) ((((long long)mod_x)+modulo)%modulo)
#define Inf 1000000000000

#define init_value 0

template <typename T>
struct segtree{
	//元データx[i]はv[n+i]
	//v[i]の親はv[i/2],子はv[i*2]とv[i*2+1]
	vector<T> v;
	int n;
	
	segtree(vector<T> &x){
		n=1;
		while(true){
			if(n>=x.size())break;
			n*=2;
		}
		v.resize(2*n,init_value);
		
		for(int i=0;i<x.size();i++){
			v[n+i]=x[i];
		}
		for(int i=n-1;i>=0;i--){
			v[i]=func(v[i*2],v[i*2+1]);
		}
	}
	
	
	void update(int x,T val){
		x+=n;
		v[x]=val;
		while(true){
			x=(x)/2;
			v[x]=func(v[x*2],v[x*2+1]);
			if(x<=0)break;
		}
	}
	
	//区間[l,r)におけるクエリ処理
	T query(int l,int r){
		T res = init_value;
		l+=n;r+=n;
		while(true){
			if(l%2==1){
				res=func(v[l],res);
				l++;
			}
			if(r%2==1){
				if(r<v.size())res=func(v[r-1],res);
				r--;
			}
			if(l>=r)break;
			l/=2;r/=2;
		}
		return res;
	}
	T func(T a,T b){
		return a+b;
	}
	
	void show(){
		int n = 1;
		for(int i=1;i<v.size();i++){
			for(int j=0;j<n;j++){
				if(j!=0)cout<<' ';
				cout<<v[i+j];
			}
			cout<<endl;
			i+=n-1;
			n*=2;
		}
	}
	
};

struct lca{
	
	vector<int> depth;//depth[i] 頂点iの深さ
	vector<vector<int>> parents;//parents[i][j] 頂点iから2^j個上の親
	
	int max_j = 30;
	
	lca(int n,vector<vector<int>> &E){
		depth.assign(E.size(),-1);
		parents.assign(E.size(),vector<int>(max_j,-1));
		
		stack<int> s;
		s.push(n);
		depth[n] = 0;
		while(s.size()!=0){
			int k = s.top();
			s.pop();
			for(int i=0;i<E[k].size();i++){
				int x = E[k][i];
				if(depth[x]!=-1)continue;
				s.push(x);
				depth[x] = depth[k]+1;
				for(int j=0;j<max_j;j++){
					if(j==0){
						parents[x][j] = k;
					}
					else{
						parents[x][j] = parents[parents[x][j-1]][j-1];
					}
					if(parents[x][j] == -1)break;
				}
			}
		}
	}
	
	//頂点uのk番目の親
	int kth_parent(int u,int k){
		for(int i=0;i<max_j;i++){
			if(k==0)break;
			if(u==-1)break;
			if(k%2){
				u = parents[u][i];
			}
			k/=2;
		}
		return u;
	}
	
	int query(int u,int v){
		if(depth[u]<depth[v])swap(u,v);
		u = kth_parent(u,depth[u]-depth[v]);
		
		if(u==v){
			return u;
		}
		
		for(int i=max_j-1;i>=0;i--){
			if(parents[u][i]!=parents[v][i]){
				u = parents[u][i];
				v = parents[v][i];
			}
		}
		
		return parents[u][0];
		
	}
	
	int get_distance(int u,int v){
		return depth[u]+depth[v]-2*depth[query(u,v)];
	}
	
	
};

vector<int> check;
vector<vector<int>> c_list;
void dfs(int n,vector<vector<int>> &E,vector<vector<pair<int,long long>>> &C,vector<long long> &V){
	check[n] = V.size()-1;
	for(int i=0;i<E[n].size();i++){
		int k = E[n][i];
		if(check[k]!=-1)continue;
		V.push_back(C[n][i].second);
		c_list[C[n][i].first].push_back(V.size()-1);
		dfs(k,E,C,V);
		V.push_back(-C[n][i].second);
		c_list[C[n][i].first].push_back(V.size()-1);
	}
	
	
}

int main(){
	
	int N,Q;
	cin>>N>>Q;
	vector<vector<int>> E(N,vector<int>(0));
	vector<vector<pair<int,long long>>> C(N,vector<pair<int,long long>>(0));
	check.resize(N,-1);
	c_list.resize(N,vector<int>(0));
	for(int i=0;i<N-1;i++){
		int a,b,c,d;
		cin>>a>>b>>c>>d;
		a--;b--;
		E[a].push_back(b);
		E[b].push_back(a);
		C[a].push_back(make_pair(c,d));
		C[b].push_back(make_pair(c,d));
	}
	

	
	int ne;
	for(int i=0;i<N;i++){
		if(E[i].size()==1){
			ne=i;
			break;
		}
	}
	lca L(ne,E);	
	vector<long long> V;
	V.push_back(0);
	dfs(ne,E,C,V);
	V.push_back(0);
	
	segtree<long long> seg(V);
	vector<tuple<int,int,int,int,int>> que;
	
	
	for(int i=0;i<Q;i++){
		int a,b,c,d;
		cin>>a>>b>>c>>d;
		c--;d--;
		que.push_back(make_tuple(a,b,c,d,i));
	}
	sort(que.begin(),que.end());
	
	
	vector<pair<int,int>> change_list(0);
	vector<long long> ans(Q);
	
	
	for(int i=0;i<que.size();i++){
		if(i==0){
			Label:
			int c = get<0>(que[i]);
			for(int j=0;j<c_list[c].size();j++){
				long long a = seg.query(c_list[c][j],c_list[c][j]+1);
				change_list.push_back(make_pair(a,c_list[c][j]));
				if(a>0)seg.update(c_list[c][j],Inf);
				else seg.update(c_list[c][j],-Inf);
			}
		}
		else{
			if(get<0>(que[i])!=get<0>(que[i-1])){
				for(int j=0;j<change_list.size();j++){
					seg.update(change_list[j].second,change_list[j].first);
				}
				change_list.clear();
				goto Label;
			}
		}
		int x= get<2>(que[i]),y=get<3>(que[i]);
		int p = L.query(x,y);
		long long aa = seg.query(0,check[x]+1)+seg.query(0,check[y]+1)-2*seg.query(0,check[p]+1);
		aa = (aa/Inf)*get<1>(que[i])+(aa%Inf);
		ans[get<4>(que[i])]=aa;
	}
	for(int i=0;i<Q;i++){
		cout<<ans[i]<<endl;
	}
		
	

	
	return 0;
}


Measured memory_bytes: 54896