#include <iostream>
#include <utility>
#include <vector>
#include <tuple>
#include <unordered_map>
#include <map>

std::vector<std::vector<std::tuple<int, int, int>>> t_arr;
std::vector<std::vector<int>> parent_arr;
std::vector<int> nstep_arr;
std::vector<std::tuple<int, int, int, int, int>> queue_arr;
std::unordered_map<int, std::vector<int>> key_nodes;
std::map<std::tuple<int, int>, std::tuple<int, int, int>> node_info;

void dfs_parent(int current, int parent, int nstep){
  parent_arr[current][0] = parent;
  nstep_arr[current] = nstep;
  for(const auto& it: t_arr.at(current)){
    if(std::get<0>(it)==parent) continue;
    dfs_parent(std::get<0>(it), current, nstep+1);
  }
}

auto lca(int node1, int node2){
  if(nstep_arr[node1] > nstep_arr[node2]) std::swap(node1, node2);
  int nstep_diff = nstep_arr[node2]-nstep_arr[node1];
  int k = 0;
  while(nstep_diff > 0){
    if(nstep_diff & 1) node2 = parent_arr[node2][k];
    k++;
    nstep_diff = nstep_diff >> 1;
  }
  while(node1 != node2){
    int k2 = 0;
    while(parent_arr[node1][k2] != parent_arr[node2][k2]) k2++;
    k2 = std::max(0, k2-1);
    node1 = parent_arr[node1][k2];
    node2 = parent_arr[node2][k2];
  }
  return node1;
}

void dfs_color(int current, int parent, int length, std::vector<int>& current_clength, std::vector<int>& current_cnum){
  if(key_nodes.count(current) > 0){
    for(const auto& color: key_nodes[current]){
      node_info.insert(std::make_pair(std::make_tuple(current, color), std::make_tuple(length, current_clength[color], current_cnum[color])));
    }
  }
  for(const auto& it: t_arr.at(current)){
    if(std::get<0>(it)==parent) continue;
    current_cnum[std::get<1>(it)]++;
    current_clength[std::get<1>(it)] += std::get<2>(it);
    dfs_color(std::get<0>(it), current, length+std::get<2>(it), current_clength, current_cnum);
    current_cnum[std::get<1>(it)]--;
    current_clength[std::get<1>(it)] -= std::get<2>(it);
  }
}

int main(){
  int N,Q;
  std::cin >> N >> Q;
  t_arr.resize(N);
  for(int i = 0; i < N-1; i++){
    int a,b,c,d;
    std::cin >> a >> b >> c >> d;
    a--; b--; c--;
    t_arr[a].push_back(std::make_tuple(b,c,d));
    t_arr[b].push_back(std::make_tuple(a,c,d));
  }

  int N_bit = 0, tmp = N;
  while(tmp > 0){ tmp = tmp >> 1; N_bit++; }
  parent_arr.resize(N, std::vector<int>(N_bit, -1));
  nstep_arr.resize(N);
  dfs_parent(0, -1, 0);
  for(int k = 0; k < N_bit-1; k++){
    for(int n = 0; n < N; n++){
      if(parent_arr[n][k] == -1) continue;
      parent_arr[n][k+1] = parent_arr[parent_arr[n][k]][k];
    }
  }

  for(int i = 0; i < Q; i++){
    int x,y,u,v;
    std::cin >> x >> y >> u >> v;
    x--; u--; v--;
    int lcauv = lca(u,v);
    queue_arr.push_back(std::make_tuple(x,y,u,v,lcauv));
    key_nodes[u].push_back(x);
    key_nodes[v].push_back(x);
    key_nodes[lcauv].push_back(x);
  }

  std::vector<int> clength(N), cnum(N);
  dfs_color(0, -1, 0, clength, cnum);

  for(const auto& it: queue_arr){
    int x = std::get<0>(it), y = std::get<1>(it);
    auto ui = node_info[std::make_pair(std::get<2>(it), x)];
    auto vi = node_info[std::make_pair(std::get<3>(it), x)];
    auto uvi = node_info[std::make_pair(std::get<4>(it), x)];
    auto l_change = [&](decltype(ui) l){ return std::get<0>(l)-std::get<1>(l)+y*std::get<2>(l); };
    int length = l_change(ui)+l_change(vi)-2*l_change(uvi);
    std::cout << length << "\n";
  }

  return 0;
}



Measured memory_bytes: 47944