#include <bits/stdc++.h>

#include <cmath>
#include <vector>

class treeutil {
  const std::vector<std::vector<int>>& g;
  const int n;
  const int root;
  std::vector<int> _depth;
  std::vector<std::vector<int>> _ancestors;

  void _calcAncestors(int p, int parent = -1) {
    if (parent < 0) {
      _depth.resize(n);
      _ancestors.resize(n);
      _depth[p] = 0;
    } else {
      _depth[p] = _depth[parent] + 1;
      _ancestors[p].push_back(parent);
      for (int i = 1; (1 << i) <= _depth[p]; ++i) {
        _ancestors[p].push_back(_ancestors[_ancestors[p][i - 1]][i - 1]);
      }
    }
    for (auto&& child : g[p]) {
      if (child == parent) continue;
      _calcAncestors(child, p);
    }
  }

 public:
  treeutil(const std::vector<std::vector<int>>& g, int root = 0)
      : g(g), n(g.size()), root(root) {}

  int depth(int p) {
    if (_depth.empty()) _calcAncestors(root);
    return _depth[p];
  }

  int ancestor(int p, int level) {
    if (_ancestors.empty()) _calcAncestors(root);
    int i = 0;
    while (level) {
      if (level & 1) p = _ancestors[p][i];
      ++i;
      level >>= 1;
    }
    return p;
  }

  int lca(int p, int q) {
    if (_ancestors.empty()) _calcAncestors(root);
    if (_depth[p] > _depth[q]) {
      p = ancestor(p, _depth[p] - _depth[q]);
    } else if (_depth[p] < _depth[q]) {
      q = ancestor(q, _depth[q] - _depth[p]);
    }
    if (p == q) return p;
    int i = std::log2(_depth[p]);
    while (_ancestors[p][i] != _ancestors[q][i]) {
      p = _ancestors[p][i];
      q = _ancestors[q][i];
      i = std::log2(_depth[p]);
    }
    while (--i >= 0) {
      if (_ancestors[p][i] != _ancestors[q][i]) {
        p = _ancestors[p][i];
        q = _ancestors[q][i];
      }
    }
    return _ancestors[p][0];
  }
};

// #LIB#

using namespace std;
using ll = long long;
#define double long double
#define rep(i, n) for (long long i = 0; i < (n); ++i)
#define repr(i, a, b) for (auto i = (a); i < (b); ++i)
#define itr(x, c) for (auto&& x : (c))
#define updatemax(t, v) ((t) = std::max((t), (v)))
#define updatemin(t, v) ((t) = std::min((t), (v)))
#define endl _endl
const char _endl = (cin.tie(0), cout.tie(0), ios::sync_with_stdio(0), cout.precision(16), '\n');

vector<vector<int>> g;
map<tuple<ll, ll>, tuple<ll, ll>> ec_el;
vector<tuple<ll, ll, ll, ll, ll>> qs;
map<tuple<ll, ll, ll>, ll> ls;
vector<set<tuple<ll, ll>>> reqs;
vector<pair<ll, ll>> cn_cl;
ll lsum = 0;
void dfs(int p, int parent = -1) {
  if (parent >= 0) {
    auto [ec, el] = ec_el[{parent, p}];
    cn_cl[ec].first += 1;
    cn_cl[ec].second += el;
    lsum += el;
  }
  itr(req, reqs[p]) {
    auto [rc, rl] = req;
    ls[{p, rc, rl}] = lsum - cn_cl[rc].second + cn_cl[rc].first * rl;
  }
  itr(child, g[p]) {
    if (child == parent) continue;
    dfs(child, p);
  }
  if (parent >= 0) {
    auto [ec, el] = ec_el[{parent, p}];
    cn_cl[ec].first -= 1;
    cn_cl[ec].second -= el;
    lsum -= el;
  }
}
int main() {
  ll n, q;
  cin >> n >> q;
  g.resize(n);
  rep(i, n - 1) {
    ll a, b, c, d;
    cin >> a >> b >> c >> d;
    --a;
    --b;
    g[a].push_back(b);
    g[b].push_back(a);
    ec_el[{a, b}] = ec_el[{b, a}] = {c, d};
  }
  treeutil gu(g);
  reqs.resize(n);
  rep(i, q) {
    ll x, y, u, v;
    cin >> x >> y >> u >> v;
    --u;
    --v;
    reqs[u].emplace(x, y);
    reqs[v].emplace(x, y);
    auto lca = gu.lca(u, v);
    reqs[lca].emplace(x, y);
    qs.emplace_back(x, y, u, v, lca);
  }
  cn_cl.resize(n);
  dfs(0);
  rep(i, q) {
    auto [x, y, u, v, lca] = qs[i];
    cout << ls[{u, x, y}] + ls[{v, x, y}] - 2 * ls[{lca, x, y}] << endl;
  }
}


Measured memory_bytes: 86328