#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define rep(i, n) FOR(i, 0, n)
#define whole(x) (x).begin(),(x).end()
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())
using P = pair<int, int>;
#define debug(var) cerr << "[" << #var << "] " << var << endl
const ll mod = 1000000007;


template<typename T> // T: type of cost
struct lca {
  int n, root, l;
  vector<vector<int>> to;
  vector<vector<T>> co;
  vector<int> dep;
  vector<T> costs;
  vector<vector<int>> par;
  lca(int n):n(n),to(n),co(n),dep(n),costs(n) {
    l = 0;
    while ((1<<l) < n) ++l;
    par = vector<vector<int>>(n+1,vector<int>(l,n));
  }
  void addEdge(int a, int b, T c=0) {
    to[a].push_back(b); co[a].push_back(c);
    to[b].push_back(a); co[b].push_back(c);
  }
  void dfs(int v, int d=0, T c=0, int p=-1) {
    if (p != -1) par[v][0] = p;
    dep[v] = d;
    costs[v] = c;
    for (int i = 0; i < to[v].size(); ++i) {
      int u = to[v][i];
      if (u == p) continue;
      dfs(u, d+1, c+co[v][i], v);
    }
  }

  void init(int _root=0) {
    root = _root;
    dfs(root);
    for (int i = 0; i < l-1; ++i) {
      for (int v = 0; v < n; ++v) {
        par[v][i+1] = par[par[v][i]][i];
      }
    }
  }
  // LCA
  int calclca(int a, int b) {
    if (dep[a] > dep[b]) swap(a,b);
    int gap = dep[b]-dep[a];
    for (int i = l-1; i >= 0; --i) {
      int len = 1<<i;
      if (gap >= len) {
        gap -= len;
        b = par[b][i];
      }
    }
    if (a == b) return a;
    for (int i = l-1; i >= 0; --i) {
      int na = par[a][i];
      int nb = par[b][i];
      if (na != nb) a = na, b = nb;
    }
    return par[a][0];
  }
  int length(int a, int b) {
    int c = calclca(a,b);
    return dep[a]+dep[b]-dep[c]*2;
  }
  T dist(int a, int b) {
    int c = calclca(a,b);
    return costs[a]+costs[b]-costs[c]*2;
  }
};

struct Edge{
    ll to, col, dist;
    Edge(ll to, ll col, ll dist): to(to), col(col), dist(dist) {}
};
struct Query{
    ll id, col, y, coeff;
    Query(ll id, ll col, ll y, ll coeff): id(id), col(col), y(y), coeff(coeff) {}
};

const ll MX = 100005;
vector<Edge> edge[MX];
vector<Query> qu[MX];
ll ans[MX];
ll colsum[MX];
ll colnum[MX];

void dfs(ll x, ll p=-1) {
    for (auto q: qu[x]) {
        ans[q.id] -= colsum[q.col] * q.coeff;
        ans[q.id] += q.coeff * q.y * colnum[q.col];
    }
    for (auto e: edge[x]) {
        if (e.to==p) continue;
        colsum[e.col] += e.dist;
        colnum[e.col]++;
        dfs(e.to, x);
        colsum[e.col] -= e.dist;
        colnum[e.col]--;
    }
}


int main(){
    ll n, q;
    cin >> n >> q;
    
    lca<ll> g(n);
    rep(i, n-1) {
        ll a, b, c, d;
        cin >> a >> b >> c >> d;
        a--; b--;
        g.addEdge(a, b, d);
        edge[a].emplace_back(b, c, d);
        edge[b].emplace_back(a, c, d);
    }
    g.init();
    
    
    rep(i, q) {
        ll x, y, u, v;
        cin >> x >> y >> u >> v;
        u--; v--;
        ll w = g.calclca(u, v);
        ans[i] = g.dist(u, v);
        qu[u].emplace_back(i, x, y, 1);
        qu[v].emplace_back(i, x, y, 1);
        qu[w].emplace_back(i, x, y, -2);
    }
    dfs(0);
    
    rep(i, q) {
        cout << ans[i] << endl;
    }
    return 0;
}


Measured memory_bytes: 54512