#include<cstdio>
#include<algorithm>
using namespace std;
int n,T,num,tot;
int rdt[200300],rd[200300],rdc[200300],rdl[200300],wz[200300],ans[200300];
int dad[200300],hvdad[200300],hvson[200300],dep[200300],sz[200300],dadlen[200300];
int trtoli[200300],litotr[200300];
int a[400300],sum[400300],L[400300],R[400300];

struct SS
{
  int ans,sum;
};

struct S
{
  int l,c,x,y,n;
}A[200050],Q[200050];


void cnct(int x,int y,int c,int l)
{
  rdt[++num]=wz[x],rd[num]=y,rdc[num]=c,rdl[num]=l,wz[x]=num;
  rdt[++num]=wz[y],rd[num]=x,rdc[num]=c,rdl[num]=l,wz[y]=num;
}

void dfs(int x,int from,int l,int d)
{
  int t=wz[x],m=0;
  dad[x]=from,sz[x]=1,dadlen[x]=l,dep[x]=d;
  while(t)
    {
      if(rd[t]!=from)
        {
		  dfs(rd[t],x,rdl[t],d+1);
		  if(sz[rd[t]]>m) m=sz[rd[t]],hvson[x]=rd[t];
		  sz[x]++;
		}
	  t=rdt[t];
	}
}

void dfs2(int x,int hd)
{
  int t=wz[x];
  trtoli[x]=++num,hvdad[x]=hd;
  litotr[num]=x;
  if(hvson[x]) dfs2(hvson[x],hd);
  while(t)
    {
      if(rd[t]!=dad[x] && rd[t]!=hvson[x])
        {
		  dfs2(rd[t],rd[t]);
		}
	  t=rdt[t];
	}
}

void Mk(int x,int l,int r)
{
  L[x]=l,R[x]=r;
  if(l!=r)
    {
	  Mk(x*2,l,(l+r)/2);
	  Mk(x*2+1,(l+r)/2+1,r);
	  a[x]=a[x*2]+a[x*2+1];
	}
  else
    {
	  a[x]=dadlen[litotr[l]];
	}
}

bool cmp(S t1,S t2)
{
  return t1.c<t2.c;
}

void updt(int x,int tar,int num,int ty)
{
  if(L[x]==R[x])
    {
	  a[x]=num,sum[x]=ty; 
	}
  else
    {
	  if(tar<L[x*2+1]) updt(x*2,tar,num,ty);
	  else updt(x*2+1,tar,num,ty);
	  a[x]=a[x*2]+a[x*2+1];
	  sum[x]=sum[x*2]+sum[x*2+1];
	}
}

void chg(int x,int y)
{
  int tar,tarnum=y;
  if(dad[A[x].x]==A[x].y) tar=trtoli[A[x].x];
  else tar=trtoli[A[x].y];
  updt(1,tar,tarnum,1);
}

void rechg(int x)
{
  int tar,tarnum=A[x].l;
  if(dad[A[x].x]==A[x].y) tar=trtoli[A[x].x];
  else tar=trtoli[A[x].y];
  updt(1,tar,tarnum,0);
}


SS getsum(int x,int l,int r)
{
  if(L[x]==l && R[x]==r) 
    {
	  SS P;
	  P.ans=a[x];
	  P.sum=sum[x];
	  return P;
	}
  else
    {
	  if(r<L[x*2+1]) return getsum(x*2,l,r);
	  else if(l>R[x*2]) return getsum(x*2+1,l,r);
	  else 
	    {
		  SS P=getsum(x*2,l,R[x*2]),PP=getsum(x*2+1,L[x*2+1],r);
		  P.ans+=PP.ans,P.sum+=PP.sum;
		  return P;
		}
	}
}

int getans(int x,int y,int t1,int t2)
{
  int ans=0,sum=0;
  SS P;
  while(hvdad[x]!=hvdad[y])
    {
	  if(dep[hvdad[x]]<dep[hvdad[y]]) swap(x,y);
	  P=getsum(1,trtoli[hvdad[x]],trtoli[x]);
	  ans+=P.ans,sum+=P.sum;
	  x=dad[hvdad[x]];
	}
  if(x!=y)
  {
  if(dep[x]<dep[y]) swap(x,y);
    P=getsum(1,trtoli[y]+1,trtoli[x]);
	  ans+=P.ans,sum+=P.sum;
  }
  return ans+sum*(Q[t2].l-Q[t1].l);
} 

int main()
{
  int i,j,k,i2,j2;
  scanf("%d%d",&n,&T);
  for(i=1;i<n;i++)
    {
     scanf("%d%d%d%d",&A[i].x,&A[i].y,&A[i].c,&A[i].l);
     cnct(A[i].x,A[i].y,A[i].c,A[i].l),A[i].n=i;
	}
  for(i=1;i<=T;i++) scanf("%d%d%d%d",&Q[i].c,&Q[i].l,&Q[i].x,&Q[i].y),Q[i].n=i;
  num=0;
  dfs(1,0,0,0);
  dfs2(1,1);
  Mk(1,1,num);
  sort(A+1,A+n,cmp);
  sort(Q+1,Q+1+T,cmp);
  i2=0;
 for(i=1;i<=T;i++)
    {
      int pd=0;
      while(A[++i2].c<Q[i].c && i2<n);
      if(A[i2].c==Q[i].c)
        {
		  for(j2=i2;A[j2].c==Q[i].c;j2++)
		    {
			  chg(j2,Q[i].l);
			}
		  pd=1;
		}
	  else i2--;
	  for(j=i+1;j<=T;j++) if(Q[j].c!=Q[i].c) break;
	  for(k=i;k<j;k++)
	    {
		  ans[Q[k].n]=getans(Q[k].x,Q[k].y,i,k);
		}
	  if(pd)
	    {
		  for(j2=i2;A[j2].c==Q[i].c;j2++)
		    {
			  rechg(j2);
			}
		  i2=j2-1;
		}
	  i=j-1;
	}
  for(i=1;i<=T;i++) printf("%d\n",ans[i]);
}

Measured memory_bytes: 30336