#include <bits/stdc++.h>

using namespace std;
#define  ll long long
#define ld long double
#define f first
#define s second
const int N = 1e5+5;

ll n , q , tim , sp[N][20] , lg=20;
ll sum[N] , totSum[N] , cnt[N] , tmpSum , in[N] , out[N]; //sum of each color + and -
vector< pair<ll , pair<ll,ll> > > color[N]; //first is time, second second is len , third is cnt
vector<ll> qq[N];
pair< pair<ll,ll> , pair<ll,ll> > qy[N];

struct edge
{
    ll to , clr , ds;
};
vector<edge> adj[N];

void dfs1(int node , int par)
{
    in[node] = ++tim;
    sp[node][0] = par;
    for(ll i=1; i<lg; i++)
    {
        ll tmp = sp[node][i-1];
        sp[node][i] = sp[tmp][i-1];
    }
    for(auto ch : adj[node])
    {
        if (ch.to != par)
            dfs1(ch.to , node);
    }
    out[node] = tim;
}

void dfs(ll node , ll par , ll c , ll d)
{
 //   sp[node][0] = par;
    in[node] = ++tim;
    sum[c] += d;
    cnt[c]++;
    tmpSum += d;
    totSum[node] = tmpSum;
    color[c].push_back({tim , {sum[c] , cnt[c]}});

    if (qq[node].size())
    {
        map<ll,bool> vis;
        for(auto cc : qq[node])
        {
            if (cc != c && vis[cc]==0)
            {
                color[cc].push_back({tim , {sum[cc] , cnt[cc]}});
                vis[cc] = 1;
            }
        }
    }

    /*
    for(ll i=1; i<lg; i++)
    {
        ll tmp = sp[node][i-1];
        sp[node][i] = sp[tmp][i-1];
    }
     */

    for(auto ch : adj[node])
    {
        if (ch.to != par)
            dfs(ch.to , node , ch.clr , ch.ds);
    }
    out[node] = tim;
    sum[c] -= d;
    tmpSum -= d;
    cnt[c]--;
}

bool is_ancestor(ll u, ll v)
{
    return in[u] <= in[v] && out[u] >= out[v];
}

ll lca(ll u, ll v)
{
    if (is_ancestor(u, v))
        return u;
    if (is_ancestor(v, u))
        return v;

    for (ll i = lg-1; i >= 0; --i)
    {
        if (!is_ancestor(sp[u][i], v))
            u = sp[u][i];
    }
    return sp[u][0];
}

ll getDs(ll x , ll y , ll lc)
{
    return totSum[x] + totSum[y] - 2*totSum[lc];
}

ll BS(ll val , vector<pair<ll , pair<ll,ll> > > &v)
{
    ll l = 0 , h=(int)v.size()-1 , mid , idx=-1;
    while(l<=h)
    {
        mid = (l+h)/2;
        if (v[mid].f <= val)
        {
            idx = max(idx , mid);
            l = mid+1;
        }
        else h=mid-1;
    }
    return idx;
}

pair<ll,ll> get(ll node , ll c)
{
    ll up =  BS(in[node] , color[c]);
  //  cout << node << ' ' << c << ' ' << up << ' ' << color[c][up].s.f << ' ' << color[c][up].s.s << " haa!\n";
    return {color[c][up].s.f , color[c][up].s.s}; //sum , count
}

ll solve(ll x , ll y , ll u , ll v)
{
    ll lc = lca(u,v) , totalDs = getDs(u,v,lc);
    pair<ll,ll> uu = get(u,x);
    pair<ll,ll> vv = get(v,x); //sum , cnt
    pair<ll,ll> lcc = get(lc,x);
  //  cout << " tot ds " << totalDs << "\n";
  //  cout << u << ' ' << v << ' ' << uu.f << ' ' << uu.s << ' ' << vv.f << ' ' << vv.s << ' ' << lcc.f << ' ' << lcc.s << " how\n";
    ll count_c = uu.s+vv.s-2*lcc.s , sum_c = uu.f+vv.f-2*lcc.f ;
    totalDs -= sum_c , totalDs += count_c*y;

    return totalDs;
}

int main()
{
    ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    cin >> n >> q;
    for(ll i=1; i<n; i++)
    {
        ll a , b , c, d;
        cin >> a >> b >> c >> d;
        edge ed;
        ed.to=b , ed.clr=c , ed.ds = d;
        adj[a].push_back(ed);
        ed.to = a;
        adj[b].push_back(ed);
    }

    dfs1(1,1);
    tim=0;
    for(int i=1; i<=q; i++)
    {
        ll x,y,u,v;
        cin >> x >> y >> u >> v;
        qq[u].push_back(x) , qq[v].push_back(x);
        int lc = lca(u,v);
        qq[lc].push_back(x);
        qy[i] = {{x,y} , {u,v}};
    }

    dfs(1,1,0,0);

    for(int i=1; i<=q; i++)
    {
        ll x,y,u,v,ans;
        x = qy[i].f.f , y=qy[i].f.s , u=qy[i].s.f , v=qy[i].s.s;
        ans = solve(x,y,u,v);
        cout << ans << '\n';
    }

    return 0;
}

Measured memory_bytes: 66500