#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define REPR(i, n) for (int i = n - 1; i >= 0; --i)
#define FOR(i, m, n) for (int i = m; i < n; ++i)
#define FORR(i, m, n) for (int i = m; i >= n; --i)
#define ALL(v) (v).begin(),(v).end()
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
const ll INF=1LL<<60;
const int inf=(1<<30)-1;
const int mod=1e9+7;
int dx[8]={1,0,-1,0,-1,-1,1,1};
int dy[8]={0,1,0,-1,-1,1,-1,1};
template< typename G >
struct DoublingLowestCommonAncestor {
  const int LOG;
  vector< int > dep;
  const G &g;
  vector< vector< int > > table;

  DoublingLowestCommonAncestor(const G &g) : g(g), dep(g.size()), LOG(32 - __builtin_clz(g.size())) {
    table.assign(LOG, vector< int >(g.size(), -1));
  }

  void dfs(int idx, int par, int d) {
    table[0][idx] = par;
    dep[idx] = d;
    for(auto &to : g[idx]) {
      if(to != par) dfs(to, idx, d + 1);
    }
  }

  void build() {
    dfs(0, -1, 0);
    for(int k = 0; k + 1 < LOG; k++) {
      for(int i = 0; i < table[k].size(); i++) {
        if(table[k][i] == -1) table[k + 1][i] = -1;
        else table[k + 1][i] = table[k][table[k][i]];
      }
    }
  }

  int query(int u, int v) {
    if(dep[u] > dep[v]) swap(u, v);
    for(int i = LOG - 1; i >= 0; i--) {
      if(((dep[v] - dep[u]) >> i) & 1) v = table[i][v];
    }
    if(u == v) return u;
    for(int i = LOG - 1; i >= 0; i--) {
      if(table[i][u] != table[i][v]) {
        u = table[i][u];
        v = table[i][v];
      }
    }
    return table[0][u];
  }
};

struct edge{ll to;ll col;ll len;};
const int nmax=100005;
vector<ll> ns(nmax),cs(nmax),dis(nmax);
vector<vector<edge>> e(nmax);
vector<vector<int>> use(nmax);
map<pair<ll,ll>,pair<ll,ll>> mp;
void dfs(int cur,int pre=-1){
    for(int x:use[cur]){
        mp[{cur,x}]={ns[x],cs[x]};
    }
    for(auto to:e[cur]){
        if(to.to==pre){
            continue;
        }
        ns[to.col]++;
        cs[to.col]+=to.len;
        dis[to.to]=dis[cur]+to.len;
        dfs(to.to,cur);
        ns[to.col]--;
        cs[to.col]-=to.len;
    }
}
int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n,q;cin >> n >> q;
    vector<vector<int>> g(n);
    REP(i,n-1){
        int a,b,c,d;cin >> a >> b >> c >> d;
        a--,b--,c--;
        e[a].push_back(edge{b,c,d});
        e[b].push_back({edge{a,c,d}});
        g[a].push_back(b);
        g[b].push_back(a);
    }
    DoublingLowestCommonAncestor<vector<vector<int>>> lca(g);
    lca.build();
    vector<int> x(q),y(q),u(q),v(q),l(q);;
    REP(i,q){
        cin >> x[i] >> y[i] >> u[i] >> v[i];
        x[i]--,y[i],u[i]--,v[i]--;
        use[u[i]].push_back(x[i]);
        use[v[i]].push_back(x[i]);
        l[i]=lca.query(u[i],v[i]);
        use[l[i]].push_back(x[i]);
    }
    dfs(0);
    REP(i,q){
        ll ans=dis[u[i]]+dis[v[i]]-2*dis[l[i]];
        auto a=mp[{u[i],x[i]}],b=mp[{v[i],x[i]}],c=mp[{l[i],x[i]}];
        ans+=(a.first+b.first-2*c.first)*y[i]-(a.second+b.second-2*c.second);
        cout << ans << endl;
    }
}

Measured memory_bytes: 58112