#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
const double eps = 1e-10;
const int MOD = 1000000007;
const int INF = 1000000000;
const ll LINF = 1ll<<50;
template<typename T>
void printv(const vector<T>& s) {
  for(int i=0;i<(int)(s.size());++i) {
    cout << s[i];
    if(i == (int)(s.size())-1) cout << endl;
    else cout << " ";
  }
}
struct Edge {
  int from, to, col, cost;
  Edge(int from, int to, int col, int cost): from(from), to(to), col(col), cost(cost) {}
};
using Graph = vector<vector<Edge>>;
int LCA(int u, int v, const vvi &par, const vi &depth) {
  if(depth[u] > depth[v]) swap(u, v);
  for(int k = 0; k < 18; ++k) {
    if((depth[v] - depth[u]) >> k & 1) {
      v = par[v][k];
    }
  }
  if(u == v) return u;
  for(int k = 17; k >= 0; k--) {
    if(par[u][k] != par[v][k]) {
      u = par[u][k];
      v = par[v][k];
    }
  }
  return par[u][0];
}
void dfs(const Graph &tr, int now, int prev, vector<ll> &nowdist, vector<ll> &nowcnt, map<int, map<int, bool>> &used, map<int, map<int, ll>> &dist, map<int, map<int, ll>> &cnt) {
  for(int i=0;i<(int)(tr[now].size());++i) {
    int next = tr[now][i].to, col = tr[now][i].col, cost = tr[now][i].cost;
    if(prev != next) {
      nowdist[col] += cost;
      nowcnt[col] += 1;
      if(used.find(next) != used.end()) {
        for(auto &e: used[next]) {
          int updcol = e.first;
          dist[next][updcol] = nowdist[updcol];
          cnt[next][updcol] = nowcnt[updcol];
        }
      }
      dfs(tr, next, now, nowdist, nowcnt, used, dist, cnt);
      nowdist[col] -= cost;
      nowcnt[col] -= 1;
    }
  }
}
int main() {
  cin.tie(0);
  cout << fixed << setprecision(10);
  int n, Q; cin >> n >> Q;
  Graph tr1(n);
  for(int i=0;i<n-1;++i) {
    int a, b, c, d; cin >> a >> b >> c >> d;
    a--; b--; c--;
    tr1[a].push_back(Edge(a, b, c, d));
    tr1[b].push_back(Edge(b, a, c, d));
  }
  vector<int> x(Q), y(Q), u(Q), v(Q);
  for(int i=0;i<Q;++i) {
    cin >> x[i] >> y[i] >> u[i] >> v[i];
    x[i]--; u[i]--; v[i]--;
  }
  Graph tr2(n);
  vvi par(n, vi(18, 0));
  vi depth(n);
  vll d(n);
  queue<P> q;
  par[0][0] = 0;
  depth[0] = 0;
  d[0] = 0;
  q.push({0, -1});
  while(!q.empty()) {
    int now = q.front().first, prev = q.front().second; q.pop();
    for(int i=0;i<(int)(tr1[now].size());++i) {
      int next = tr1[now][i].to;
      if(next != prev) {
        tr2[now].push_back(Edge(now, next, tr1[now][i].col, tr1[now][i].cost));
        par[next][0] = now;
        depth[next] = depth[now] + 1;
        d[next] = d[now] + tr1[now][i].cost;
        q.push({next, now});
      }
    }
  }
  for(int i=1;i<18;++i) {
    for(int j=0;j<n;++j) {
      par[j][i] = par[par[j][i-1]][i-1];
    }
  }
  map<pair<int, int>, int> lca;
  map<int, map<int, bool>> used;
  for(int i=0;i<Q;++i) {
    lca[{u[i], v[i]}] = LCA(u[i], v[i], par, depth);
    used[u[i]][x[i]] = true;
    used[v[i]][x[i]] = true;
    used[lca[{u[i], v[i]}]][x[i]] = true;
  }
  map<int, map<int, ll>> dist;
  map<int, map<int, ll>> cnt;
  vector<ll> nowdist(100000);
  vector<ll> nowcnt(100000);
  dfs(tr2, 0, -1, nowdist, nowcnt, used, dist, cnt);
  for(int i=0;i<Q;++i) {
    int tmplca = lca[{u[i], v[i]}];
    ll tmpd = d[u[i]] + d[v[i]] - 2 * d[tmplca];
    ll tmpdist = dist[u[i]][x[i]] + dist[v[i]][x[i]] - 2 * dist[tmplca][x[i]];
    ll tmpcnt = cnt[u[i]][x[i]] + cnt[v[i]][x[i]] - 2 * cnt[tmplca][x[i]];
    cout << tmpd - tmpdist + y[i] * tmpcnt << endl;
  }
}


Measured memory_bytes: 105332