#include <bits/stdc++.h>
#define FOR(i,k,n)  for(int i = (k);i < (n);++i)
#define REP(i,n)    FOR(i,0,n)
#define ALL(x)      begin(x),end(x)

using namespace std;
using vecint = vector<int>;
using ll = int64_t;

struct Edge {
  int src,dest,clr,dist;
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;

void dfs(const Graph& g, vecint& euler_in, vecint& euler_out, int& euler_id, int i, int p) {
  euler_in[i] = euler_id;
  ++euler_id;
  for (auto&& e : g[i]) {
    if (e.dest == p) continue;
    dfs(g, euler_in, euler_out, euler_id, e.dest, i);
  }
  euler_out[i] = euler_id;
}

struct LCA {
  int V, LOG_V;
  vector<vector<int>> parent;
  vector<int> depth;
  void dfs(const Graph &g, int v, int p, int d) {
    parent[0][v] = p; depth[v] = d;
    for (Edge e: g[v]) if (e.dest != p) dfs(g, e.dest, v, d + 1);
  }
  LCA(const Graph &g, int root) : V(g.size()), LOG_V(0), depth(V, 0) {
    for (int v = V; v > 0; v >>= 1) ++LOG_V;
    parent.assign(LOG_V, vector<int>(V, 0));
    dfs(g, root, -1, 0);
    REP(k, LOG_V - 1) REP(v, 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);
    REP(k, LOG_V) if (((depth[v] - depth[u]) >> k) & 1) v = parent[k][v];
    if (u == v) return u;
    for (int k = LOG_V - 1; k >= 0; k--) {
      if (parent[k][u] != parent[k][v]) {
        u = parent[k][u];
        v = parent[k][v];
      }
    }
    return parent[0][u];
  }
};

struct Data {
  int num;
  Data() : num(0) {;}
  Data(int n) : num(n) {;}
  operator int() const { return num; }
};

inline Data Merge(Data left, Data right) {
  return Data(left.num + right.num);
}

struct SegmentTree {
  int n; vector<Data> data;
  SegmentTree(int N) : n(1 << N), data(n * 2) {}
  Data get(int pos) {
    Data result(0);
    result = Merge(result, data[pos]);
    while (pos < 2*n-1) {
      pos = pos / 2 + n;
      result = Merge(result, data[pos]);
    }
    return result;
  }
  void sub(Data val, int fr, int to, int node, int la, int ra) {
    if (ra<=fr || to<=la) return;
    if (fr<=la && ra<=to) {
      data[node] = Merge(data[node], val);
      return;
    }
    sub(val, fr, to, (node-n)*2+0, la, (la+ra)/2);
    sub(val, fr, to, (node-n)*2+1, (la+ra)/2, ra);
  }
  void query(int fr, int to, Data val) { sub(val, fr, to, 2*n-2, 0, n); }
};

int main()
{
  int n,q;
  cin>>n>>q;
  Graph g(n);
  Graph vc(n);
  Edges ve;
  REP(i,n-1) {
    int a,b,c,d;
    cin>>a>>b>>c>>d;
    --a;--b;
    g[a].push_back((Edge){a,b,c,d});
    g[b].push_back((Edge){b,a,c,d});
    vc[c].push_back((Edge){a,b,c,d});
    ve.push_back((Edge){a,b,c,d});
  }
  vecint euler_in(n), euler_out(n);
  int euler_id = 0;
  dfs(g, euler_in, euler_out, euler_id, 0, -1);
  SegmentTree st(17);
  for(auto&& e:ve) {
    int in = max(euler_in[e.src], euler_in[e.dest]);
    int out = min(euler_out[e.src], euler_out[e.dest]);
    st.query(in, out, e.dist);
  }
  vector<tuple<int,int,int,int,int>> vt;
  REP(i,q) {
    int x,y,u,v;
    cin>>x>>y>>u>>v;
    --u;--v;
    vt.emplace_back(x,y,u,v,i);
  }
  sort(ALL(vt));
  LCA lca(g, 0);
  auto itr = begin(vt);
  vecint ans(q);
  SegmentTree cnt(17);
  FOR(i,1,n) {
    for(auto&& e:vc[i]) {
      int in = max(euler_in[e.src], euler_in[e.dest]);
      int out = min(euler_out[e.src], euler_out[e.dest]);
      st.query(in, out, -e.dist);
      cnt.query(in, out, 1);
    }
    while (itr != end(vt)) {
      int x,y,u,v,j;
      tie(x,y,u,v,j) = *itr;
      if (x != i) break;
      ++itr;
      int l = lca.lca(u,v);
      int eu = euler_in[u], ev = euler_in[v], el = euler_in[l];
      int others = st.get(eu) + st.get(ev) - 2*st.get(el);
      int changed = y * (cnt.get(eu) + cnt.get(ev) - 2*cnt.get(el));
      ans[j] = others + changed;
    }
    for(auto&& e:vc[i]) {
      int in = max(euler_in[e.src], euler_in[e.dest]);
      int out = min(euler_out[e.src], euler_out[e.dest]);
      st.query(in, out, e.dist);
      cnt.query(in, out, -1);
    }
  }
  for(auto&& e:ans) {
    cout<<e<<'\n';
  }
  cout<<flush;
  return 0;
}


Measured memory_bytes: 33636