#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <utility>
#define maxn 100005
#define maxq 100005
#define mp make_pair

using namespace std;
typedef long long ll;
const int LEN = 100000;
typedef pair<int,int> P;

struct fastio{
  char s[LEN + 5]; int len,it;
  fastio(){
    it = len = 0;
  }
  char get(){
    if(it < len) return s[it++];
    it = 0, len = fread(s,1,LEN,stdin);
    return len ? s[it++] : EOF;
  }
  bool notend(){
    char c;
    for(c = get();c == ' ' || c == '\n';c = get());
    if(it) it--;
    return c != EOF;
  }
  void put(char c){
    if(len == LEN) fwrite(s,1,LEN,stdout), len = 0;
    s[len++] = c;
  }
  void flush(){
    fwrite(s,1,len,stdout);
    len = 0;
  }
}buff,bufo;
inline int getint(){
  char c; int res = 0, sig = 1;
  for(c = buff.get();c < '0' || c > '9';c = buff.get()) if(c == '-') sig = -1;
  for(;c >= '0' && c <= '9';c = buff.get())
    res = (res << 3) + (res << 1) + (c - '0');
  return sig * res;
}
inline void putll(ll x){
  if(!x) bufo.put('0');
  else if(x < 0) bufo.put('-'), x = -x;
  char s[25]; int k = 0;
  while(x){
    s[++k] = x % 10 + '0';
    x /= 10;
  }
  for(int i = k;i >= 1;i--) bufo.put(s[i]);
}

int n,q;
struct edge{
  int to,id;
  edge(int to = 0,int id = 0): to(to),id(id) {}
};
vector <edge> adj[maxn];
int cst[maxn];
int maxlog = 17, t[18][maxn << 1],k,row[maxn << 1],dep[maxn],sum[maxn],lk;
int id[maxn];
int eid[maxn][2],bit2[maxn << 1],bit1[maxn << 1];
void add(int* bit,int pos,int x){
  for(int i = pos;i <= lk;i += i & -i) bit[i] += x;
}
int query(int* bit,int pos){
  int res = 0;
  for(int i = pos;i;i -= i & -i) res += bit[i];
  return res;
}
int min_(int a,int b){
  return dep[a] < dep[b] ? a : b;
}
void dfs(int u,int f){
  t[0][++lk] = u;
  id[u] = lk;
  dep[u] = (f == -1) ? 0 : dep[f] + 1;
  for(int i = 0;i < (int)adj[u].size();i++){
    edge e = adj[u][i];
    if(e.to == f) continue;
    eid[e.id][0] = lk + 1;
    sum[e.to] = sum[u] + cst[e.id];
    dfs(e.to,u);
    t[0][++lk] = u;
    eid[e.id][1] = lk;
  }
}
void rmq_ini(){
  int st = 2;
  for(int i = 1;i <= lk;i++){
    if(i == st){
      row[i] = row[i - 1] + 1;
      st <<= 1;
    }else{
      row[i] = row[i - 1];
    }
  }
  for(int i = 1;i <= maxlog;i++){
    for(int j = 1;j + (1 << i) - 1 <= lk;j++){
      t[i][j] = min_(t[i - 1][j],t[i - 1][j + (1 << (i - 1))]);
    }
  }
}
int lca(int u,int v){
  u = id[u], v = id[v];
  if(u == v) return t[0][u];
  if(u > v) swap(u,v);
  int ro = row[v - u];
  return min_(t[ro][u],t[ro][v - (1 << ro) + 1]);
}
vector <int> color[maxn];//edge ids.
struct Query{
  int y,u,v,id;
  Query(int y = 0,int u = 0,int v = 0,int id = 0): y(y),u(u),v(v),id(id) {}
};
vector <Query> qcol[maxn];
ll ans[maxq];

int main(){
  n = getint(), q = getint();
  for(int i = 1;i < n;i++){
    int u = getint(), v = getint(), c = getint(), d = getint();
    color[c].push_back(i);
    cst[i] = d;
    adj[u].push_back(edge(v,i));
    adj[v].push_back(edge(u,i));
  }
  dfs(1,-1);
  rmq_ini();
  for(int i = 1;i <= q;i++){
    int x = getint(), y = getint(), u = getint(), v = getint();
    qcol[x].push_back(Query(y,u,v,i));
  }
  for(int i = 1;i < n;i++){
    if(qcol[i].size() == 0) continue;
    for(int j = 0;j < (int)color[i].size();j++){
      int id = color[i][j];
      add(bit1,eid[id][0],1);
      add(bit1,eid[id][1],-1);
      add(bit2,eid[id][0],cst[id]);
      add(bit2,eid[id][1],-cst[id]);
    }
    for(int j = 0;j < (int)qcol[i].size();j++){
      Query q1 = qcol[i][j];
      int p = lca(q1.u,q1.v);
      ll res = (ll)sum[q1.u] + sum[q1.v] - 2ll * sum[p];
      res -= (ll)query(bit2,id[q1.u]) + query(bit2,id[q1.v]) - 2ll * query(bit2,id[p]);
      res += (ll)q1.y * (query(bit1,id[q1.u]) + query(bit1,id[q1.v]) - 2 * query(bit1,id[p]));
      ans[q1.id] = res;
    }
    for(int j = 0;j < (int)color[i].size();j++){
      int id = color[i][j];
      add(bit1,eid[id][0],-1);
      add(bit1,eid[id][1],1);
      add(bit2,eid[id][0],-cst[id]);
      add(bit2,eid[id][1],cst[id]);
    }
  }
  for(int i = 1;i <= q;i++){
    putll(ans[i]); bufo.put('\n');
  }
  bufo.flush();
  return 0;
}


Measured memory_bytes: 40052