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

struct Edge{
    int to;
    int nex;
    int co;
    int w;
}e[N<<1];

int tot,head[N],a[N];

void add(int u,int v,int co,int w){
    e[tot].to=v;
    e[tot].w=w;
    e[tot].co=co;
    e[tot].nex=head[u];
    head[u]=tot++;
}

/*---------树链剖分---------*/
int fa[N],sizee[N],son[N],d[N],bl[N];
int who[N],id[N],cntt;
int col[N],val[N],pre[N];

void dfs1(int u,int co,int w){
    sizee[u]=1;
    son[u]=0;
    col[u]=co;
    val[u]=w;
    for(int i=head[u];i!=-1;i=e[i].nex){
        int v=e[i].to;
        int w=e[i].w;
        int co=e[i].co;
        if(v!=fa[u]){
            fa[v]=u;
            d[v]=d[u]+1;
            a[v]=e[i].w;
            dfs1(v,co,w);
            sizee[u]+=sizee[v];
            if(sizee[v]>sizee[son[u]]){
                son[u]=v;
            }
        }
    }
}

void dfs2(int u,int chain){
    bl[u]=chain;
    id[u]=++cntt;
    who[cntt]=u;
    if(son[u]) dfs2(son[u],chain);
    for(int i=head[u];i!=-1;i=e[i].nex){
        int v=e[i].to;
        if(v!=son[u]&&v!=fa[u]){
            dfs2(v,v);
        }
    }
}
/*---------树链剖分---------*/

/*----------主席树----------*/
int ls[N*30],rs[N*30],sum[N*30],sz=0,rt[N],num[N*30];

void update(int &x,int y,int l,int r,int pos,int w){
    x=++sz; ls[x]=ls[y]; rs[x]=rs[y];
    num[x]=num[y]+1;
    sum[x]=sum[y]+w;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(pos<=mid) update(ls[x],ls[y],l,mid,pos,w);
    else update(rs[x],rs[y],mid+1,r,pos,w);
}

int query1(int x,int y,int l,int r,int k){
    //cout<<k<<" "<<l<<" "<<r<<endl;
    if(l==r){
            //cout<<k<<" "<<num[x]<<" "<<num[y]<<endl;
            return num[x]-num[y];
    }
    int mid=(l+r)>>1;
    if(k<=mid) return query1(ls[x],ls[y],l,mid,k);
    if(k>mid)  return query1(rs[x],rs[y],mid+1,r,k);
};

int query2(int x,int y,int l,int r,int k){
    if(l==r) return sum[x]-sum[y];
    int mid=(l+r)>>1;
    if(k<=mid) return query2(ls[x],ls[y],l,mid,k);
    if(k>mid)  return query2(rs[x],rs[y],mid+1,r,k);
};


/*----------主席树----------*/

/*---------树剖加主席树-----*/

int no=0,ss=0,ans=0,n;

void ask(int x,int y,int co){
    int res=0;
    //cout<<bl[x]<<" "<<bl[y]<<endl;
    while(bl[x]!=bl[y]){
        if(d[bl[x]]<d[bl[y]]){
            swap(x,y);
        }
        no+=query1(rt[id[x]],rt[id[bl[x]]-1],1,n,co);
        ss+=query2(rt[id[x]],rt[id[bl[x]]-1],1,n,co);
        //cout<<id[x]<<" "<<id[bl[x]]-1<<endl;
        ans+=pre[id[x]]-pre[id[bl[x]]-1];
        x=fa[bl[x]];
    }
    if(d[x]>d[y]) swap(x,y);
    if(x==y) return;
    //cout<<x<<"@@"<<y<<endl;
    no+=query1(rt[id[y]],rt[id[son[x]]-1],1,n,co);
    ss+=query2(rt[id[y]],rt[id[son[x]]-1],1,n,co);
    //cout<<id[y]<<" "<<id[son[x]]-1<<endl;
    ans+=pre[id[y]]-pre[id[son[x]]-1];

}

/*---------树剖加主席树-----*/


int main(){
    memset(head,-1,sizeof head);
    int q,x,y,z,w;
    cin>>n>>q;
    for(int i=1;i<=n-1;i++){
        scanf("%d%d%d%d",&x,&y,&z,&w);
        add(x,y,z,w);
        add(y,x,z,w);
    }
    dfs1(1,0,0);
    dfs2(1,1);
    for(int i=1;i<=n;i++){
        x=who[i];
        update(rt[i],rt[i-1],1,n,col[x],val[x]);
        pre[i]=pre[i-1]+val[x];
    }
    while(q--){
        ans=ss=no=0;
        scanf("%d%d%d%d",&z,&w,&x,&y);
        ask(x,y,z);
        ans+=no*w-ss;
        printf("%d\n",ans);
    }
}


Measured memory_bytes: 55552