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

struct edge{
    int y,c,w;
    edge(){y=c=w=0;}
    edge(int _y,int _c,int _w){y=_y;c=_c;w=_w;}
};

int n,q;
vector<edge> g[100005];
int hson[100005],fa[100005],dep[100005],sz[100005],top[100005],dfn[100005],dfncnt,rnk[100005];

int hldprec(int x,int p,int d){
    dep[x]=d;
    sz[x]=1;
    for(edge &e:g[x])if(e.y!=p){
        sz[x]+=hldprec(e.y,x,d+e.w);
        fa[e.y]=x;
        if(sz[e.y]>sz[hson[x]]){
            hson[x]=e.y;
        }
    }
    return sz[x];
}

void hlddec(int x,int head){
    top[x]=head;
    dfn[x]=++dfncnt;
    rnk[dfncnt]=x;
    if(hson[x]){
        hlddec(hson[x],head);
        for(edge &e:g[x])if(e.y!=fa[x]&&e.y!=hson[x]){
            hlddec(e.y,e.y);
        }
    }
}

int lca(int u,int v){
    while(top[u]!=top[v]){
        if(dep[top[u]]>dep[top[v]]){
            u=fa[top[u]];
        }else{
            v=fa[top[v]];
        }
    }
    return dep[u]<dep[v]?u:v;
}

inline int dis(const int &u,const int &v){
    return dep[u]+dep[v]-(dep[lca(u,v)]<<1);
}

struct query{
    int id,w,u,v;
    query(){
        id=w=u=v=0;
    }
    query(int a,int b,int c,int d){
        id=a;w=b;u=c;v=d;
    }
};

vector<edge> e[100005];
vector<query> qs[100005];
int ans[100005];
int cnt[100005],sum[100005];

int get(int *bit,int pos){
    int res=0;
    while(pos>0){
        res+=bit[pos];
        pos-=pos&-pos;
    }
    return res;
}

void add(int *bit,int pos,int val){
    while(pos<=n){
        bit[pos]+=val;
        pos+=pos&-pos;
    }
}

int deal(int *bit,int u,int v){
    int res=0;
    while(top[u]!=top[v]){
        if(dep[top[u]]>dep[top[v]]){
            res+=get(bit,dfn[u])-get(bit,dfn[top[u]]-1);
            u=fa[top[u]];
        }else{
            res+=get(bit,dfn[v])-get(bit,dfn[top[v]]-1);
            v=fa[top[v]];
        }
    }
    res+=get(bit,max(dfn[u],dfn[v]))-get(bit,min(dfn[u],dfn[v]));
    return res;
}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin>>n>>q;
    for(int i=1;i<n;i++){
        int x,y,c,w;
        cin>>x>>y>>c>>w;
        g[x].emplace_back(y,c,w);
        g[y].emplace_back(x,c,w);
        e[c].emplace_back(x,y,w);
    }
    hldprec(1,-1,0);
    hlddec(1,1);
    for(int i=1;i<=q;i++){
        int x,y,u,v;
        cin>>x>>y>>u>>v;
        qs[x].emplace_back(i,y,u,v);
    }
    for(int color=1;color<n;color++){
        for(int i=0;i<e[color].size();i++){
            edge &ce=e[color][i];
            if(dep[ce.y]>dep[ce.c]){
                add(sum,dfn[ce.y],ce.w);
                add(cnt,dfn[ce.y],1);
            }else{
                add(sum,dfn[ce.c],ce.w);
                add(cnt,dfn[ce.c],1);
            }
        }
        for(int i=0;i<qs[color].size();i++){
            query &q=qs[color][i];
            ans[q.id]=dis(q.u,q.v)+q.w*deal(cnt,q.u,q.v)-deal(sum,q.u,q.v);
        }
        for(int i=0;i<e[color].size();i++){
            edge &ce=e[color][i];
            if(dep[ce.y]>dep[ce.c]){
                add(sum,dfn[ce.y],-ce.w);
                add(cnt,dfn[ce.y],-1);
            }else{
                add(sum,dfn[ce.c],-ce.w);
                add(cnt,dfn[ce.c],-1);
            }
        }
    }
    for(int i=1;i<=q;i++){
        cout<<ans[i]<<'\n';
    }

    return 0;
}

Measured memory_bytes: 26724