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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update> 
#define ll long long

#ifdef sarthak
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cout << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
int begtime = clock();
#else
#define trace(...)
#endif

#ifndef sarthak
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize("unroll-loops")
    // #pragma GCC target ("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#endif

#define foreach(it,ar) for (auto it = ar.begin(); it != ar.end(); it++)
#define fort(i,v) for(auto i:v)
#define fr(i,a,b) for (ll i = (a), _b = (b); i <= _b; i++)
#define frr(i,a,b) for (ll i = (a), _b = (b); i >= _b; i--)
#define rep(i,n) for (ll i = 0, _n = (n); i < _n; i++)
#define repr(i,n) for (ll i = n - 1; i >= 0; i--)
#define fill(ar,val) rep(i,sizeof(ar)/sizeof(ll)) ar[i]=val
#define fill2(ar,val) rep(i,sizeof(ar)/sizeof(ar[0])) rep(j,sizeof(ar[0])/sizeof(ll)) ar[i][j]=val
#define fill0(ar) memset(ar,0,sizeof(ar))
#define debug(x) cout<<#x<<": "<<x<<endl

#define ld long double
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define sd2(x,y) scanf("%d %d",&x,&y)
#define slld2(x,y) scanf("%lld %lld",&x,&y)
#define pd(x) printf("%d\n",x)
#define plld(x) printf("%lld\n",x)
#define pd2(x,y) printf("%d %d\n",x,y)
#define plld2(x,y) printf("%lld %lld\n",x,y)
#define all(ar) ar.begin(), ar.end()
#define endl '\n'
#define sz(x) (int)x.size()
#define len(x) (int)x.length()

typedef pair<ll, ll> ii;
typedef pair<ii, ll> iii;
typedef vector<ii> vii;
typedef vector<ll> vi;

#define INF 1000000000000000000
#define PI 3.14159265358979323846L

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rngb(chrono::steady_clock::now().time_since_epoch().count()); // can give negative values too

vector<pair<ll, pair<ll, ll> > > ed2[100001];

const ll N = 100001;
const ll K = 35;
ll up[N][K+1];
ll tin[N];
ll tout[N];
ll timer = 0;
vector<ll> ed[N];
// Run dfs as preprocess step !
void dfs(ll src, ll par)    // src and par are both root intially !
{
    tin[src] = timer;
    timer++;

    up[src][0] = par;
    fr(i,1,K)
    {
        up[src][i] = up[up[src][i-1]][i-1];
    }

    rep(i,ed[src].size())
    {
        if(ed[src][i]!=par)
            dfs(ed[src][i],src);
    }

    tout[src] = timer;
}

bool isAncestor(ll u, ll v)
{
    if(tin[u] <= tin[v] && tout[u]>=tout[v])
        return true;
    return false;
}

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

    frr(i,K,0)
    {
        if(!isAncestor(up[u][i],v))
            u = up[u][i];
    }

    return up[u][0];
}

map<ll, ll> m[N];
map<ll, pair<ll, ll> > m2[N];
pair<ll, ll> num[N];
ll dd[N];

void DFS2(ll src, ll par)
{
    foreach(it,m[src])
    {
        ll col = it->first;
        m2[src][col] = num[col];
    }

    fort(v,ed2[src])
    {
        if(v.ff==par)
            continue;
        ll col = v.ss.ff;
        ll len = v.ss.ss;
        ll vert = v.ff;

        num[col].ff++;
        num[col].ss += len;
        DFS2(vert,src);
        num[col].ff--;
        num[col].ss -= len;
    }
}

void DFS3(ll src, ll par)
{
    fort(v,ed2[src])
    {
        ll vert = v.ff;
        ll len = v.ss.ss;
        if(vert==par)
            continue;
        dd[vert] = dd[src] + len;
        DFS3(vert,src);
    }
}

void solve()
{
    ll n;
    cin >> n;

    ll q;
    cin >> q;

    rep(i,n-1)
    {
        ll a,b,c,d;
        cin >> a >> b >> c >> d;
        ed2[a].pb(mp(b,mp(c,d)));
        ed2[b].pb(mp(a,mp(c,d)));
        ed[a].pb(b);
        ed[b].pb(a);
    }

    dfs(1,1);

    pair<pair<ll, ll>, pair<ll, ll> > p[q];
    rep(i,q)
    {
        ll x,y,u,v;
        cin >> x >> y >> u >> v;
        p[i] = mp(mp(x,y),mp(u,v));
        m[u][x]++;
        m[v][x]++;
        m[lca(u,v)][x]++;
    }

    DFS2(1,0);
    DFS3(1,0);
    // trace(dd[4]);
    rep(i,q)
    {
        ll x = p[i].ff.ff;
        ll y = p[i].ff.ss;
        ll u = p[i].ss.ff;
        ll v = p[i].ss.ss;

        ll lc = lca(u,v);
        ll ans = dd[u]+dd[v]-(2*dd[lc]);
        // trace(ans,u,v,lc);
        ll num = 0;
        ll len = 0;
        num = m2[u][x].ff+m2[v][x].ff-(2*m2[lc][x].ff);
        len = m2[u][x].ss+m2[v][x].ss-(2*m2[lc][x].ss);

        ans = ans - len;
        ans = ans + (num*y);
        cout << ans << endl;
    }

}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout << fixed;
    cout << setprecision(10);
    #ifdef sarthak
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif

    ll t = 1;
    // cin >> t;
    while(t--)
    {
        solve();
    }

    #ifdef sarthak
    cerr << "Time elapsed: " << (clock() - begtime)*1000/CLOCKS_PER_SEC << " ms\n\n";
    #endif
}


Measured memory_bytes: 91316