#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef long long ll;
typedef long double ld;
const int inf=1e9+7;
const ll longinf=1LL<<60;
#define REP(i,m,n) for(int i=(int)(m) ; i < (int) (n) ; ++i )
#define rep(i,n) REP(i,0,n)
#define F first
#define S second
constexpr char ln = '\n';

const int mx=100010;
const ll mod=1e9+7;

class LCA{ //autumn_eel
public:
  vector<vector<pair<long long,int>>>E;
  vector<vector<int>>par,w;
  vector<int>d1;
  vector<long long>d2;
  int MAX_LOG=22;
  int n;
  LCA(){}
  LCA(int N){
    n=N;
    E=vector<vector<pair<long long,int>>>(n);
    par=w=vector<vector<int>>(MAX_LOG,vector<int>(n));
    d1=vector<int>(n);
    d2=vector<long long>(n);
  }
  void add_edge(int a,int b,int c){
    E[a].push_back(make_pair(c,b));
    E[b].push_back(make_pair(c,a));
  }
  void add_edge(int a,int b){
    E[a].push_back(make_pair(1,b));
    E[b].push_back(make_pair(1,a));
  }
private:
  void dfs(int u,int p,int a,long long b, long long s){
    par[0][u]=p;d1[u]=a;d2[u]=s;w[0][u]=b;
    for(auto&v:E[u]){
      if(v.second!=p)dfs(v.second,u,a+1,v.first,s+v.first);
    }
  }
  bool flag=false;
  void init(){
    dfs(0,-1,0,0,0);
    for(int i=1;i<MAX_LOG;i++)for(int j=0;j<n;j++){
      if(par[i-1][j]==-1)par[i][j]=-1,w[i][j]=w[i-1][j];
      else par[i][j]=par[i-1][par[i-1][j]],w[i][j]=max(w[i-1][j],w[i-1][par[i-1][j]]);
    }
    flag=true;
  }
public:
  int query(int u,int v){ //経路内の辺の重みのmaxを返す
    if(!flag)init();
    if(d1[u]>d1[v])swap(u,v);
    int res=0;
    for(int i=0;i<MAX_LOG;i++){
      if((d1[v]-d1[u])>>i&1)res=max(res,w[i][v]),v=par[i][v];
    }
    if(u==v)return res;
    for(int i=MAX_LOG-1;i>=0;i--){
      if(par[i][u]!=par[i][v]){
        res=max(res,w[i][u]);
        res=max(res,w[i][v]);
        u=par[i][u];
        v=par[i][v];
      }
    }
    res=max(res,w[0][u]);
    res=max(res,w[0][v]);
    return res;
  }
  int calc_lca(int u, int v){
    if(!flag)init();
    if(d1[u]>d1[v])swap(u,v);
    for(int i=0;i<MAX_LOG;i++){
      if((d1[v]-d1[u])>>i&1) v=par[i][v];
    }
    if(u==v)return u;
    for(int i=MAX_LOG-1;i>=0;i--){
      if(par[i][u]!=par[i][v]){
        u = par[i][u];
            v = par[i][v];
      }
    }
    return par[0][u];
  }
  long long calc_dist(int u,int v){
	  int l=calc_lca(u,v);
    return d2[u]+d2[v]-d2[l]*2;	  //d2 距離の差
//    return d1[u]+d1[v]-d1[l]*2;   //d1 深さの差
  }
};

vector<pair<int,P>> e[mx]; //to, color, dist
map<int,int> color_num[mx], color_dist[mx]; //color[i][colot] node i ,color ne made
int tc_num[mx],tc_dist[mx];
vector<int> node_color[mx]; //

void dfs(int now, int p){
  for(auto it:node_color[now]){
    color_num[now][it] = tc_num[it];
    color_dist[now][it] = tc_dist[it];
  }
  for(auto& it:e[now]){
    if(it.F==p) continue;
    tc_dist[it.S.F] += it.S.S;
    tc_num[it.S.F] += 1;
    dfs(it.F,now);
    tc_dist[it.S.F] -= it.S.S;
    tc_num[it.S.F] -= 1;
  }
}

int main(){
  int n,q;
  cin >> n >> q;
  vector<int> a(n),b(n),c(n),d(n),x(q),y(q),u(q),v(q),lca_node(q);
  LCA lca(n);
  rep(i,n-1){
    cin >> a[i] >> b[i] >> c[i] >> d[i]; a[i]--; b[i]--; c[i]--;
    lca.add_edge(a[i], b[i], d[i]);
    e[a[i]].push_back({b[i],{c[i],d[i]}});
    e[b[i]].push_back({a[i],{c[i],d[i]}});
  }
  rep(i,q){
    cin >> x[i] >> y[i] >> u[i] >> v[i]; u[i]--; v[i]--; x[i]--;
    lca_node[i] = lca.calc_lca(u[i],v[i]);
    node_color[u[i]].emplace_back(x[i]);
    node_color[v[i]].emplace_back(x[i]);
    node_color[lca_node[i]].emplace_back(x[i]);
  }
  dfs(0,-1);
  rep(i,q){
    ll XXX = (color_num[u[i]][x[i]] + color_num[v[i]][x[i]] - 2*color_num[lca_node[i]][x[i]])*y[i] - (color_dist[u[i]][x[i]] + color_dist[v[i]][x[i]] - 2*color_dist[lca_node[i]][x[i]]);
    ll ans = lca.calc_dist(u[i],v[i]) + XXX;
    cout << ans << ln;
  }

  return 0;
}

Measured memory_bytes: 78836