#include <bits/stdc++.h>
using namespace std;

# define REP(i,n) for (int i=0;i<(n);++i)
# define rep(i,a,b) for(int i=a;i<(b);++i)
# define p(s) std::cout << s ;
# define pl(s)  std::cout << s << endl;
# define printIf(j,s1,s2) cout << (j ? s1 : s2) << endl;
# define YES(j) cout << (j ? "YES" : "NO") << endl;
# define Yes(j) std::cout << (j ? "Yes" : "No") << endl;
# define yes(j) std::cout << (j ? "yes" : "no") << endl;
# define all(v) v.begin(),v.end()
# define showVector(v) REP(i,v.size()){p(v[i]);p(" ")} pl("")
template<class T> inline bool chmin(T &a, T b){ if(a > b) { a = b; return true;} return false;}
template<class T> inline bool chmax(T &a, T b){ if(a < b) { a = b; return true;} return false;}
typedef long long int ll;
typedef pair<ll,ll> P_ii;
typedef pair<double,double> P_dd;

template<class T>
vector<T> make_vec(size_t a){
    return vector<T>(a);
}

template<class T, class... Ts>
auto make_vec(size_t a, Ts... ts){
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}

template<typename T,typename V>
typename enable_if<is_class<T>::value==0>::type
fill_v(T &t,const V &v){t=v;}

template<typename T,typename V>
typename enable_if<is_class<T>::value!=0>::type
fill_v(T &t,const V &v){
  for(auto &e:t) fill_v(e,v);
}


const int MOD = 1000000007;
const int inf=1e9+7;
const ll longinf=1LL<<60 ;

void addM(long long &a, long long b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

void mulM(long long &a, long long b) {
    a = ((a%MOD)*(b%MOD))%MOD ;
}

template<typename T>
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 getLCA(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 = getLCA(a,b);
    return dep[a]+dep[b]-dep[c]*2;
  }
  T dist(int a, int b) {
    int c = getLCA(a,b);
    return costs[a]+costs[b]-costs[c]*2;
  }
};
 
const int MX = 100005;
struct Edge {
  int to, co, col;
  Edge(int to, int co, int col):to(to),co(co),col(col) {}
};
vector<Edge> es[MX];
 
vector<ll> ans;
struct Query {
  int col, qid, coeff, y;
  Query(int col, int qid, int coeff, int y):col(col),qid(qid),coeff(coeff),y(y) {}
};
vector<Query> qs[MX];
int cnt[MX];
ll sum[MX];
 
void dfs(int v, int p=-1) {
  for (auto q : qs[v]) {
    ll x = -sum[q.col];
    x += (ll)q.y*cnt[q.col];
    ans[q.qid] += x*q.coeff;
  }
  for (auto e : es[v]) {
    if (e.to == p) continue;
    cnt[e.col]++; sum[e.col] += e.co;
    dfs(e.to, v);
    cnt[e.col]--; sum[e.col] -= e.co;
  }
}
 
int main() {
  int n, q;
  cin >> n >> q;
  lca<ll> g(n);
  REP(i,n-1) {
    int a, b, c, d;
    cin >> a >> b >> c >> d;
    --a; --b;
    es[a].emplace_back(b,d,c);
    es[b].emplace_back(a,d,c);
    g.addEdge(a,b,d);
  }
  g.init();
  ans = vector<ll>(q);
  REP(i,q) {
    int x, y, a, b;
    cin >> x >> y >> a >> b;
    --a; --b;
    int c = g.getLCA(a,b);
    ans[i] = g.dist(a, b);
    qs[a].emplace_back(x,i,1,y);
    qs[b].emplace_back(x,i,1,y);
    qs[c].emplace_back(x,i,-2,y);
  }
  dfs(0);
  REP(i,q) cout << ans[i] << endl;;
  return 0;
}


Measured memory_bytes: 44660