#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxd = 2e5+10;
struct {int v,net,col,c;}e[maxd<<1];
int f[maxd],eid;
int n,m;
int fa[maxd],son[maxd],d[maxd],tp[maxd];
int w[maxd],col[maxd],sz[maxd];
int len[maxd];
int rt[maxd],cnt,ls[maxd*40],rs[maxd*40],size[maxd*40];
int val[maxd*40];

void insert(int x,int y,int z,int l)
{
    e[eid].net = f[x];
    e[eid].v = y;
    e[eid].c = l;
    e[eid].col = z;
    f[x] = eid++;
}
void init()
{
    memset(f,-1,sizeof(f));
    eid = 0;
}
void dfs(int x,int p = 0)
{
    fa[x] = p;d[x] = d[p]+1;
    sz[x]++;
    for(int i=f[x];i+1;i=e[i].net)
    {
        int v = e[i].v;
        if(v == p) continue;
        w[v] = e[i].c;
        col[v] = e[i].col;
        len[v] = 1ll * len[x] + w[v];
        dfs(v,x);
        if(sz[v] > sz[son[x]]) son[x] = v;
        sz[x] += sz[v];
    }
}
void dfs1(int x,int p = 1)
{
    tp[x] = p;
    if(son[x]) dfs1(son[x],p);
    for(int i=f[x];i+1;i=e[i].net)
    {
        int v = e[i].v;
        if(v==fa[x]||v==son[x]) continue;
        dfs1(v,v);
    }
}
int lca(int x,int y)
{
    while(tp[x]!=tp[y])
    {
        //printf("%d %d\n",x,y);
        if(d[tp[x]] < d[tp[y]]) swap(x,y);
        x = fa[tp[x]];
    }
    //printf("%d %d\n",x,y);
    return d[x] < d[y]? x:y;
}
void insert(int &root,int last,int l,int r,int x)
{
    root = ++cnt; ls[root] = ls[last],rs[root]=rs[last];
    val[root] = 1ll * val[last] + w[x]; size[root] = size[last]+1;

    //printf("%d %d %d %d %d %d\n",root,last,l,r,x,size[root]);
    if(l==r) return;
    int mid = (l+r)>>1;
    if(col[x] <= mid) insert(ls[root],ls[last],l,mid,x);
    else insert(rs[root],rs[last],mid+1,r,x);
}
int query(int root,int l,int r,int x)
{
    if(!root) return 0;
    if(l == r ) return root;
    int mid = (l+r)>>1;
    if(x <=mid) return query(ls[root],l,mid,x);
    else return query(rs[root],mid+1,r,x);
}
void build(int x)
{
    insert(rt[x],rt[fa[x]],1,n,x);
    // insert(rt[3],rt[fa[3]],1,n,3);
    // insert(rt[2],rt[fa[2]],1,n,2);
    // printf("%d\n",x);
    for(int i=f[x];i+1;i=e[i].net)
        if(e[i].v!=fa[x]) build(e[i].v);
}
int main()
{
    // freopen("a.in","r",stdin);
    // freopen("k.out","w",stdout);
    init();
    scanf("%d %d",&n,&m);
    for(int i=1;i<n;i++)
    {
        int a,b,c,d;
        scanf("%d %d %d %d",&a,&b,&c,&d);
        insert(a,b,c,d); insert(b,a,c,d);
    }
    dfs(1);
    dfs1(1);

    // for(int i=1;i<=n;i++)
    //     printf("%d %d\n",i,son[i]);
    n++;
    col[1] = n;
    //printf("%d\n",lca(8,3));
    build(1);
    int a,b,c,d;
    // for(int i=1;i<=n;i++)
    // {
    //     a = query(rt[3],1,n,i);
    //     printf("%d %d %d\n",val[a],size[a],a);
    // }
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d %d",&c,&d,&a,&b);
        int g = lca(a,b);
        int ans =  len[a] + len[b] - 2*len[g];
        //printf("%d %d ",g,c);
        g = query(rt[g],1,n,c);
        //printf("%d\n",g);
        a = query(rt[a],1,n,c);
        b = query(rt[b],1,n,c);
        //printf("%d %d %d\n",g,size[g],val[g]);
        ans += (size[a] + size[b] - 2*size[g]) * d;
        ans -= (val[a] + val[b] - 2*val[g]);
        printf("%d\n",ans);
    }
    return 0;
}

Measured memory_bytes: 53120