#include <bits/stdc++.h>
template<typename T>
class fixed_point : T {
  public:
    explicit constexpr fixed_point (T&& t)
      : T(std::forward<T>(t)) {}
    template<typename... Args>
    constexpr decltype(auto) operator()(Args&&... args) const
      {return T::operator()(*this, std::forward<Args>(args)...);}
};
template<typename T>
static inline constexpr decltype(auto) fix (T&& t) {
  return fixed_point<T>{std::forward<T>(t)};
}
// Class for calculating LCA.
// Dependent libraries: Combinator.
template <typename T>
class lca_t {
    struct edge {
        size_t to; T cost;
        edge(size_t to, T cost) : to(to), cost(cost){}
      };
    size_t n, lg;
    std::vector<std::vector<edge>>   graph;
    std::vector<unsigned>            depth;
    std::vector<T>                   weighted_depth;
    std::vector<std::vector<size_t>> prt;
  public:
    using cost_type = T;
    lca_t(size_t n) :
      n(n), lg(std::log2(n)),
      graph(n), depth(n, 0), weighted_depth(n, 0),
      prt(lg + 1, std::vector<size_t>(n)) {}
    // Insert an edge.
    void insert (size_t u, size_t v, T cost = 1) {
        graph.at(u).emplace_back(v, cost);
        graph.at(v).emplace_back(u, cost);
      }
    // Build a doubling table.
    void init (size_t root = 0) {
        fix ([&](auto dfs, size_t crr, size_t p) -> void {
          prt.at(0).at(crr) = p;
          for (auto const& e : graph.at(crr)) {
            if (e.to == p) continue;
            depth.at(e.to) = depth.at(crr) + 1;
            weighted_depth.at(e.to) = weighted_depth.at(crr) + e.cost;
            dfs(e.to, crr);
          }
        })(root, root);
        for (size_t p = 1; p <= lg; p++) {
          for (size_t i = 0; i < n; i++) {
            prt.at(p).at(i) = prt.at(p - 1).at(prt.at(p - 1).at(i));
          }
        }
      }
    // Calculate the lca.
    auto operator()(size_t u, size_t v) const -> size_t {
        if (depth.at(u) < depth.at(v)) std::swap(u, v);
        auto diff = depth.at(u) - depth.at(v);
        if (diff > 0) {
          for (size_t p = lg, q = std::pow(2, lg); p <= lg; p--, q /= 2) {
            if (diff > q) u = prt.at(p).at(u), diff -= q;
          }
          u = prt.at(0).at(u), diff--;
        }
        assert(diff == 0), assert(depth.at(u) == depth.at(v));
        if (u == v) return u;
        for (size_t p = lg, q = std::pow(2, lg); p <= lg; p--, q /= 2) {
          auto next_u = prt.at(p).at(u);
          auto next_v = prt.at(p).at(v);
          if (next_u != next_v) u = next_u, v = next_v;
        }
        assert(u != v);
        u = prt.at(0).at(u), v = prt.at(0).at(v), assert(u == v);
        return u;
      }
    // Calculate the count-based distance.
    auto row_dist (size_t u, size_t v) const -> unsigned {
      return depth.at(u) + depth.at(v) - 2 * depth.at(operator()(u, v));}
    // Calculate the count-based distance.
    auto weighted_dist (size_t u, size_t v) const -> T {
      auto& x = weighted_depth;
      return x.at(u) + x.at(v) - 2 * x.at(operator()(u, v));}
};
int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  size_t n, q; std::cin >> n >> q;
  lca_t<int> lca(n);
  struct edge_t {size_t to; int c, d;};
  std::vector<std::vector<edge_t>> graph(n);
  for (size_t i = 0; i < n - 1; i++) {
    size_t a, b; int c, d;
    std::cin >> a >> b >> c >> d;
    a--, b--;
    lca.insert(a, b);
    graph.at(a).push_back({b, c, d});
    graph.at(b).push_back({a, c, d});
  }
  int root = 0; lca.init(root);
  struct query_t {size_t id; int x, y, coeff;};
  std::vector<std::vector<query_t>> queries(n);
  for (size_t i = 0; i < q; i++) {
    int x, y, u, v;
    std::cin >> x >> y >> u >> v;
    u--, v--;
    queries.at(u).push_back({i, x, y, 1});
    queries.at(v).push_back({i, x, y, 1});
    queries.at(lca(u, v)).push_back({i, x, y, -2});
  }
  std::vector<unsigned> cnt(n);
  std::vector<int> dst(n), ans(q);
  int depth = 0;
  auto advance = [&] (int c, int d, int coeff) {
    cnt.at(c) += coeff;
    dst.at(c) += d * coeff;
    depth     += d * coeff;
  };
  fix ([&](auto dfs, size_t crr, size_t prt) -> void {
    for (auto q : queries.at(crr)) {
      ans.at(q.id) += (depth - dst.at(q.x) + (cnt.at(q.x) * q.y)) * q.coeff;
    }
    for (auto const& e : graph.at(crr)) {
      if ((e.to) == prt) continue;
      advance(e.c, e.d, +1);
      dfs(e.to, crr);
      advance(e.c, e.d, -1);
    }
  })(root, root);
  std::for_each(ans.begin(), ans.end(), [](auto x){std::cout << x << std::endl;});
  return 0;
}


Measured memory_bytes: 52208