#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

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

struct LCA{
  static const int BITLEN_MAX = 30;
  vector<int> parent[BITLEN_MAX];
  vector<int> depth;
  int bitlen;
  
  LCA(){}
  LCA(int N, const vector<int> edges[], int root=0){ initialize(N, edges, root); }
  void initialize(int N, const vector<int> edges[], int root){
    bitlen = 1;
    while((1<<bitlen) < N) bitlen += 1;
    for(int i=0; i<bitlen; i++) parent[i].resize(N);
    depth.resize(N, -1);    
    dfs(root, -1, 0, edges);
    for(int k=0; k<bitlen-1; k++){
      for(int v=0; v<N; v++){
        if(depth[v] == -1) continue;
        if(parent[k][v] < 0){
          parent[k+1][v] = -1;
        } else {
          parent[k+1][v] = parent[k][parent[k][v]];
        }
      }
    }
  }
  
  void dfs(int v, int p, int d, const vector<int> edges[]){
    parent[0][v] = p;
    depth[v] = d;
    for(auto u : edges[v]){
      if(u != p) dfs(u, v, d+1, edges);
    }
  }
 
  int calc_lca(int u, int v){
    if(depth[u] > depth[v]) swap(u, v);
    for(int k=0; k<bitlen; k++){
      if( ((depth[v]-depth[u]) >> k) & 1 ) v = parent[k][v];
    }
    if(u == v) return u;
    for(int k=bitlen-1; k>=0; k--){
      if(parent[k][u] != parent[k][v]){
        u = parent[k][u];
        v = parent[k][v];
      }
    }
    return parent[0][u];
  }
 
  int calc_dist(int u, int v){
    int l = calc_lca(u, v);
    return depth[u] + depth[v] - depth[l]*2;
  }
};
 
vector<vector<int>> edges[mx];
vector<int> edges2[mx];

vector<int> need[mx];
map<int, int> res_num[mx], res_sum[mx];  
// res_num[i][c]: 頂点iから根までの色cの辺の本数。res_sumはその長さ合計
 
int dist[mx];  // 根からの距離
int now_num[mx], now_sum[mx];  
// now_num[c]: 今見ている頂点から根までの色cの辺の本数。now_sumはその長さ合計

void dfs(int i, int p){
  for(auto it:need[i]){
    res_num[i][it] = now_num[it];
    res_sum[i][it] = now_sum[it];
  }
  for(auto& e:edges[i]){
    int j=e[0], c=e[1], d=e[2];
    if(j==p) continue;
    dist[j] = dist[i] + d;
    now_num[c]++;
    now_sum[c] += d;
    dfs(j, i);
    now_num[c]--;
    now_sum[c] -= d;
  }
}

int main(){
  int n,q;
  cin >> n >> q;
  for(int i=0; i<n-1; i++){
    int a,b,c,d; cin >> a >> b >> c >> d; a--; b--; c--;
    edges[a].push_back({b,c,d});
    edges[b].push_back({a,c,d});
    edges2[a].emplace_back(b);
    edges2[b].emplace_back(a);
  }
  LCA lca(n, edges2, 0);

  vector<int> x(mx), y(mx), u(mx), v(mx), l(mx);
  rep(i,q){
    cin >> x[i] >> y[i] >> u[i] >> v[i]; x[i]--; u[i]--; v[i]--;
    l[i] = lca.calc_lca(u[i], v[i]);
    need[u[i]].push_back(x[i]);
    need[v[i]].push_back(x[i]);
    need[l[i]].push_back(x[i]);
  }
  dfs(0,-1);
  rep(i,q){
    int du = dist[u[i]] - res_sum[u[i]][x[i]] + res_num[u[i]][x[i]] * y[i];
    int dv = dist[v[i]] - res_sum[v[i]][x[i]] + res_num[v[i]][x[i]] * y[i];
    int dl = dist[l[i]] - res_sum[l[i]][x[i]] + res_num[l[i]][x[i]] * y[i];
    int ans = du + dv - 2*dl;
    cout << ans << endl;
  }
  return 0;
}


Measured memory_bytes: 73268