#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
class LowestCommonAncestor {
private:
  static const int MAX_SIZE = 30;
  vector<vector<int>> graph;
  vector<int> parent[MAX_SIZE];
  vector<int> depth;
  int bit_length;
  void copy(const vector<int> g[], int siz) { 
    graph.resize(siz);
    for (int i = 0; i < siz; ++i) for (int j : g[i]) graph[i].push_back(j);
  }
  void copy(const vector<vector<int>>& g, int siz = -1) {
    if (siz < 0) siz = (int) g.size();
    graph.resize(siz);
    for (int i = 0; i < siz; ++i) for (int j : g[i]) graph[i].push_back(j);
  }
  void initialize() {
    int siz = (int) graph.size();
    int root = 0;
    bit_length = 1;
    while ((1 << bit_length) < siz) ++bit_length;
    for (int i = 0; i < bit_length; ++i) parent[i].resize(siz);
    depth.assign(siz, -1);
    dfs(root, -1, 0);
    for (int i = 0; i < bit_length- 1; ++i) {
      for (int v = 0; v < siz; ++v) {
        if (depth[v] == -1) continue;
        if (parent[i][v] < 0) parent[i + 1][v] = -1;
        else parent[i + 1][v] = parent[i][parent[i][v]];
      }
    }
  }
  void dfs(int cur, int par, int d) {
    parent[0][cur] = par;
    depth[cur] = d;
    for (int child : graph[cur]) if (child != par) dfs(child, cur, d + 1);
  }
public:
  LowestCommonAncestor() {}
  LowestCommonAncestor(const vector<vector<int>>& g, int siz = -1) { build(g, siz); }
  LowestCommonAncestor(const vector<int> g[], int siz) { build(g, siz); }
  void build(const vector<int> g[], int siz) { copy(g, siz); initialize(); }
  void build(const vector<vector<int>>& g, int siz = -1) { copy(g, siz); initialize(); }
  int get(int u, int v) {
    if (depth[u] > depth[v]) swap(u, v);
    for (int i = 0; i < bit_length; ++i) if (((depth[v] - depth[u]) >> i) & 1) v = parent[i][v];
    if (u == v) return u;
    for (int i = bit_length - 1; i >= 0; --i) if (parent[i][u] != parent[i][v]) u = parent[i][u], v = parent[i][v];
    return parent[0][u];
  }
};
using LCA = LowestCommonAncestor;
int n;
vector<vector<int>> g1[101010];
vector<int> g2[101010];
vector<int> need[101010];
map<int, int> res_cnt[101010], res_sum[101010];
int dist[101010];
int col_cnt[101010], col_sum[101010];
void dfs(int cur, int par) {
  for (int c : need[cur]) {
    res_cnt[cur][c] = col_cnt[c];
    res_sum[cur][c] = col_sum[c];
  }
  for (auto nxt: g1[cur]) {
    int child = nxt[0];
    int c = nxt[1];
    int d = nxt[2];
    if (child == par) continue;
    dist[child] = dist[cur] + d;
    col_cnt[c]++;
    col_sum[c] += d;
    dfs(child, cur);
    col_cnt[c]--;
    col_sum[c] -= d;
  }
}
signed main() { 
  ios::sync_with_stdio(false); cin.tie(0);
  int q;
  cin >> n >> q;
  for (int i = 0; i + 1 < n; i++) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    a--;
    b--;
    c--;
    g1[a].push_back({b, c, d});
    g1[b].push_back({a, c, d});
    g2[a].push_back(b);
    g2[b].push_back(a);
  }
  LCA lca(g2, n);
  vector<int> inx(q), iny(q), inu(q), inv(q), inw(q);
  for (int i = 0; i < q; i++) {
    cin >> inx[i] >> iny[i] >> inu[i] >> inv[i];
    inx[i]--;
    inu[i]--;
    inv[i]--;
    inw[i] = lca.get(inu[i], inv[i]);
    need[inu[i]].push_back(inx[i]);
    need[inv[i]].push_back(inx[i]);
    need[inw[i]].push_back(inx[i]);
  }
  dfs(0, -1);
  for (int i = 0; i < q; i++) {
    int du = dist[inu[i]] - res_sum[inu[i]][inx[i]] + res_cnt[inu[i]][inx[i]] * iny[i];
    int dv = dist[inv[i]] - res_sum[inv[i]][inx[i]] + res_cnt[inv[i]][inx[i]] * iny[i];
    int dw = dist[inw[i]] - res_sum[inw[i]][inx[i]] + res_cnt[inw[i]][inx[i]] * iny[i];
    cout << du + dv - 2 * dw << '\n';
  }
  return 0;
}

Measured memory_bytes: 80308