#include<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
//BEGIN CUT HERE
class EulerTourForEdge{
private:
  vector<int> ds,us,dep;
  int pos;

  void dfs(int v,int p,int d){
    dep[v]=d;
    for(int u:G[v]){
      if(u==p) continue;
      ds[u]=pos++;
      dfs(u,v,d+1);
      us[u]=pos++;
    }
  }
public:
  vector<vector<int> > G;

  EulerTourForEdge(){}
  EulerTourForEdge(int n):
    ds(n),us(n),dep(n),G(n){}

  void add_edge(int u,int v){
    G[u].emplace_back(v);
    G[v].emplace_back(u);
  }

  void build(int r=0){
    pos=0;
    dfs(r,-1,0);
  }

  int child(int u,int v){
    return dep[u]<dep[v]?v:u;
  }

  template<typename T,typename F>
  T query(int v,F f){
    return f(0,us[v]);
  }

  template<typename T,typename F>
  T query(int u,int v,F f){
    if(dep[u]<dep[v]) swap(u,v);
    return query<T>(u,f)-query<T>(v,f);
  }

  template<typename T,typename G>
  void update(int v,T x,G g){
    g(ds[v],+x);
    g(us[v],-x);
  }
};
//END CUT HERE

template<typename T>
struct BIT{
  int n;
  vector<T> bit;
  //1-indexed
  BIT():n(-1){}
  BIT(int n_,T d):n(n_),bit(n_+1,d){}

  T sum(int i){
    T s=bit[0];
    for(int x=i;x>0;x-=(x&-x))
      s+=bit[x];
    return s;
  }
  void add(int i,T a){
    if(i==0) return;
    for(int x=i;x<=n;x+=(x&-x))
      bit[x]+=a;
  }

  int lower_bound(int w){
    if(w<=0) return 0;
    int x=0,r=1;
    while(r<n) r<<=1;
    for(int k=r;k>0;k>>=1){
      if(x+k<=n&&bit[x+k]<w){
        w-=bit[x+k];
        x+=k;
      }
    }
    return x+1;
  }

  T sum0(int i){
    return sum(i+1);
  }
  void add0(int i,T a){
    add(i+1,a);
  }

  T query(int l,int r){
    return sum(r-1)-sum(l-1);
  }

  T query0(int l,int r){
    return sum(r)-sum(l);
  }
};


struct LowestCommonAncestor{
  int n,h;
  vector<vector<int> > G,par;
  vector<int> dep;
  LowestCommonAncestor(){}
  LowestCommonAncestor(int n):n(n),G(n),dep(n){
    h=1;
    while((1<<h)<=n) h++;
    par.assign(h,vector<int>(n,-1));
  }

  void add_edge(int u,int v){
    G[u].emplace_back(v);
    G[v].emplace_back(u);
  }

  void dfs(int v,int p,int d){
    par[0][v]=p;
    dep[v]=d;
    for(int u:G[v])
      if(u!=p) dfs(u,v,d+1);
  }

  void build(int r=0){
    dfs(r,-1,0);
    for(int k=0;k+1<h;k++){
      for(int v=0;v<n;v++){
        if(par[k][v]<0) par[k+1][v]=-1;
        else par[k+1][v]=par[k][par[k][v]];
      }
    }
  }

  int lca(int u,int v){
    if(dep[u]>dep[v]) swap(u,v);
    for(int k=0;k<h;k++){
      if((dep[v]-dep[u])>>k&1){
        v=par[k][v];
      }
    }
    if(u==v) return u;
    for(int k=h-1;k>=0;k--){
      if(par[k][u]!=par[k][v]){
        u=par[k][u];
        v=par[k][v];
      }
    }
    return par[0][u];
  }

  int distance(int u,int v){
    return dep[u]+dep[v]-dep[lca(u,v)]*2;
  }
};


template <typename T>
struct SegmentTree{
  using F = function<T(T,T)>;
  int n;
  F f;
  T ti;
  vector<T> dat;
  SegmentTree(){};
  SegmentTree(F f,T ti):f(f),ti(ti){}
  void init(int n_){
    n=1;
    while(n<n_) n<<=1;
    dat.assign(n<<1,ti);
  }
  void build(const vector<T> &v){
    int n_=v.size();
    init(n_);
    for(int i=0;i<n_;i++) dat[n+i]=v[i];
    for(int i=n-1;i;i--)
      dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
  }
  void set_val(int k,T x){
    dat[k+=n]=x;
    while(k>>=1)
      dat[k]=f(dat[(k<<1)|0],dat[(k<<1)|1]);
  }
  T query(int a,int b){
    T vl=ti,vr=ti;
    for(int l=a+n,r=b+n;l<r;l>>=1,r>>=1) {
      if(l&1) vl=f(vl,dat[l++]);
      if(r&1) vr=f(dat[--r],vr);
    }
    return f(vl,vr);
  }
  template<typename C>
  int find(int st,C &check,T &acc,int k,int l,int r){
    if(l+1==r){
      acc=f(acc,dat[k]);
      return check(acc)?k-n:-1;
    }
    int m=(l+r)>>1;
    if(m<=st) return find(st,check,acc,(k<<1)|1,m,r);
    if(st<=l&&!check(f(acc,dat[k]))){
      acc=f(acc,dat[k]);
      return -1;
    }
    int vl=find(st,check,acc,(k<<1)|0,l,m);
    if(~vl) return vl;
    return find(st,check,acc,(k<<1)|1,m,r);
  }
  template<typename C>
  int find(int st,C &check){
    T acc=ti;
    return find(st,check,acc,1,0,n);
  }
};

//INSERT ABOVE HERE
signed AOJ_GRL_5_D(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n;
  cin>>n;
  EulerTourForEdge et(n);
  for(int i=0;i<n;i++){
    int k;
    cin>>k;
    for(int j=0;j<k;j++){
      int c;
      cin>>c;
      et.add_edge(i,c);
    }
  }
  et.build();

  BIT<int> bit(n*2+100,0);
  int q;
  cin>>q;
  for(int i=0;i<q;i++){
    int t;
    cin>>t;
    if(t==0){
      int v,w;
      cin>>v>>w;
      auto g=[&](int k,int d){bit.add0(k,d);};
      et.update(v,w,g);
    }
    if(t==1){
      int u;
      cin>>u;
      auto f=[&](int l,int r){return bit.query0(l,r);};
      cout<<et.query<int>(u,f)<<"\n";
    }
  }
  cout<<flush;
  return 0;
}
/*
  verified on 2019/07/08
  http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_5_D&lang=jp
*/

signed ABC133_F(){
  cin.tie(0);
  ios::sync_with_stdio(0);

  int n,q;
  cin>>n>>q;
  vector<int> as(n),bs(n),cs(n),ds(n);
  vector<int> xs(q),ys(q),us(q),vs(q);

  vector< vector<int> > C(n),D(n);
  EulerTourForEdge et(n);
  LowestCommonAncestor lca(n);
  for(int i=1;i<n;i++){
    cin>>as[i]>>bs[i]>>cs[i]>>ds[i];
    as[i]--;bs[i]--;
    et.add_edge(as[i],bs[i]);
    lca.add_edge(as[i],bs[i]);
    C[cs[i]].emplace_back(i);
  }
  et.build();
  lca.build();

  for(int i=0;i<q;i++){
    cin>>xs[i]>>ys[i]>>us[i]>>vs[i];
    us[i]--;vs[i]--;
    D[xs[i]].emplace_back(i);
  }

  auto f=[&](int a,int b){return a+b;};
  int ti=0;
  SegmentTree<int> cnt(f,ti);
  SegmentTree<int> sum(f,ti);
  cnt.build(vector<int>(n*2,0));
  sum.build(vector<int>(n*2,0));

  for(int i=1;i<n;i++){
    int ch=et.child(as[i],bs[i]);
    auto g=[&](int v,int d){sum.set_val(v,d);};
    et.update(ch,ds[i],g);
  }

  vector<int> ans(q,0);
  for(int i=0;i<q;i++){
    int r=lca.lca(us[i],vs[i]);
    auto f=[&](int l,int r){return sum.query(l,r);};
    ans[i]+=et.query<int>(r,us[i],f);
    ans[i]+=et.query<int>(r,vs[i],f);
  }
  sum.build(vector<int>(n*2,0));

  for(int t=1;t<n;t++){
    for(int i:C[t]){
      int ch=et.child(as[i],bs[i]);

      auto g1=[&](int v,int d){cnt.set_val(v,d);};
      auto g2=[&](int v,int d){sum.set_val(v,d);};
      et.update(ch,1,g1);
      et.update(ch,ds[i],g2);
    }

    for(int i:D[t]){
      int res=0,num=0;
      int r=lca.lca(us[i],vs[i]);
      auto f1=[&](int l,int r){return cnt.query(l,r);};
      auto f2=[&](int l,int r){return sum.query(l,r);};
      num+=et.query<int>(r,us[i],f1);
      num+=et.query<int>(r,vs[i],f1);
      res+=et.query<int>(r,us[i],f2);
      res+=et.query<int>(r,vs[i],f2);
      ans[i]+=num*ys[i];
      ans[i]-=res;
    }

    for(int i:C[t]){
      int ch=et.child(as[i],bs[i]);
      auto g1=[&](int v,int d){cnt.set_val(v,d);};
      auto g2=[&](int v,int d){sum.set_val(v,d);};
      et.update(ch,0,g1);
      et.update(ch,0,g2);
    }
  }

  for(int i=0;i<q;i++) cout<<ans[i]<<"\n";
  cout<<flush;
  return 0;
}
/*
  verified on 2019/07/08
  https://atcoder.jp/contests/abc133/tasks/abc133_f
*/
signed main(){
  //AOJ_GRL_5_D();
  ABC133_F();
  return 0;
}


Measured memory_bytes: 38760