#include <bits/stdc++.h>
using namespace std;
#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define FOR(it, c) \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
typedef long long ll;
typedef unsigned long long ull;

class LabeledTreeDistance {
  struct Edge {
    int src, dst;
    int label;
    int dist;
    int cusum_num;
    int cusum_dist;
  };
  static const int root = 0;
  int N, L;
  std::vector<std::vector<Edge>> edges;

  std::vector<std::vector<std::pair<int, Edge>>> labeled;
  std::vector<Edge> tour;
  std::unordered_map<int, int> v2idx;

  void dfs(int now, int prev) {
    v2idx[now] = tour.size() - 1;
    for (int i = 0; i < edges[now].size(); i++) {
      if (edges[now][i].dst == prev) continue;
      Edge e = edges[now][i];
      tour.push_back(e);
      dfs(e.dst, now);
      e.src = e.dst;
      e.dst = now;
      e.dist = -e.dist;
      tour.push_back(e);
    }
  }

 public:
  LabeledTreeDistance(int N, int L) : N(N), L(L), edges(N), labeled(L) {
  }

  void add_edge(int a, int b, int l, int d) {
    edges[a].push_back((Edge){a, b, l, d, 0, 0});
    edges[b].push_back((Edge){b, a, l, d, 0, 0});
  }

  void build() {
    dfs(root, -1);

    int cusum_num = 0, cusum_dist = 0;
    for (int i = 0; i < tour.size(); i++) {
      cusum_num += (tour[i].dist >= 0) ? 1 : -1;
      cusum_dist += tour[i].dist;
      tour[i].cusum_num = cusum_num;
      tour[i].cusum_dist = cusum_dist;
      labeled[tour[i].label].emplace_back(i, tour[i]);
    }
    for (int i = 0; i < labeled.size(); i++) {
      cusum_num = 0;
      cusum_dist = 0;
      for (int j = 0; j < labeled[i].size(); j++) {
        cusum_num += (labeled[i][j].second.dist >= 0) ? 1 : -1;
        cusum_dist += labeled[i][j].second.dist;
        labeled[i][j].second.cusum_num = cusum_num;
        labeled[i][j].second.cusum_dist = cusum_dist;
      }
    }
  }

  std::pair<int, int> get(int v) {
    if (v == root) return std::make_pair(0, 0);
    int idx = v2idx[v];
    return std::make_pair(tour[idx].cusum_num, tour[idx].cusum_dist);
  }

  std::pair<int, int> get(int label, int v) {
    if (v == root) return std::make_pair(0, 0);
    int idx = v2idx[v];
    if (labeled[label].size() == 0) return std::make_pair(0, 0);
    int lb = -1, ub = labeled[label].size();
    while (ub - lb > 1) {
      int mid = (lb + ub) / 2;
      int lidx = -1;
      if (mid >= 0) lidx = labeled[label][mid].first;
      if (lidx <= idx)
        lb = mid;
      else
        ub = mid;
    }
    if (lb == -1)
      return std::make_pair(0, 0);
    else
      return std::make_pair(labeled[label][lb].second.cusum_num,
                            labeled[label][lb].second.cusum_dist);
  }
};

int N;
vector<int> G[100005];
int parent[64][100005];
int depth[100005];
void dfs(int v, int p, int d) {
  parent[0][v] = p;
  depth[v] = d;
  for (int i = 0; i < G[v].size(); i++) {
    if (G[v][i] != p) dfs(G[v][i], v, d + 1);
  }
}
void init(int root) {
  dfs(root, -1, 0);
  for (int k = 0; k + 1 < 64; k++) {
    for (int v = 0; v < N + 1; v++) {
      if (parent[k][v] < 0)
        parent[k + 1][v] = -1;
      else
        parent[k + 1][v] = parent[k][parent[k][v]];
    }
  }
}
int lca(int u, int v) {
  if (depth[u] > depth[v]) swap(u, v);
  for (int k = 0; k < 64; k++) {
    if ((depth[v] - depth[u]) >> k & 1) {
      v = parent[k][v];
    }
  }
  if (u == v) return u;
  for (int k = 64 - 1; k >= 0; k--) {
    if (parent[k][u] != parent[k][v]) {
      u = parent[k][u];
      v = parent[k][v];
    }
  }
  return parent[0][u];
}

int main() {
  int Q;
  cin >> N >> Q;
  vector<vector<int>> v;
  LabeledTreeDistance ltd(N, N - 1);
  rep(i, N - 1) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    a--;
    b--;
    c--;
    v.push_back({a, b, c, d});
    ltd.add_edge(a, b, c, d);
    G[a].push_back(b);
    G[b].push_back(a);
  }

  ltd.build();
  init(0);

  for (int i = 0; i < Q; i++) {
    int x, y, a, b;
    cin >> x >> y >> a >> b;
    x--;
    a--;
    b--;

    int c = lca(a, b);

    ll m1 = ltd.get(a).second + ltd.get(b).second - 2LL * ltd.get(c).second;
    ll m2 = ltd.get(x, a).second + ltd.get(x, b).second -
            2LL * ltd.get(x, c).second;
    ll c2 =
        ltd.get(x, a).first + ltd.get(x, b).first - 2LL * ltd.get(x, c).first;

    ll ret = m1 - m2 + c2 * y;

    cout << ret << endl;
  }

  return 0;
}


Measured memory_bytes: 73256