#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,fma,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file  
#include <ext/pb_ds/tree_policy.hpp>  
#include <functional> // for less  
#include <iostream>  
using namespace __gnu_pbds;  
using namespace std;
#define ll long long
typedef tree<pair<ll,ll>, null_type, less<pair<ll,ll>>, rb_tree_tag,tree_order_statistics_node_update>  ordered_set;
using namespace std;
 
#define fr(i,a,b) for (int i = (a), _b = (b); i <= _b; i++)
#define frr(i,a,b) for (int i = (a), _b = (b); i >= _b; i--)
#define rep(i,n) for (long long i = 0, _n = (n); i < _n; i++)
#define repr(i,n) for (long long i = (n) - 1; i >= 0; i--)
#define foreach(it,ar) for ( typeof(ar.begin()) it = ar.begin(); it != ar.end(); it++ )
#define fill(ar,val) memset(ar, val, sizeof(ar))
#define fill0(ar) fill((ar), 0)
#define fillinf(ar, n) fr(i,0,(n)) ar[i] = INF
#define debug(x) cout<<#x<<": "<<x<<endl
#define arr1d(a,n) cout << #a << " : "; fr(_,1,n) cout << a[_] << ' '; cout << endl;
#define arr1d0(a,n) cout << #a << " : "; rep(_,n) cout << a[_] << ' '; cout << endl;
#define arr2d(a,n,m) cout << #a << " :" << endl; fr(_,1,n) {fr(__,1,m) cout << a[_][__] << ' '; cout << endl;}
#define arr2d0(a,n,m) cout << #a << " :" << endl; rep(_,n) {rep(__,m) cout << a[_][__] << ' '; cout << endl;}
/*Author Ritick Goenka || ritick(codechef) ||ritick(codeforces) */
/*IIT Roorkee = <3 */
#define ull unsigned long long
#define ld long double
#define ui unsigned int
#define all(ar) ar.begin(), ar.end()
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define y0 yyyyyy0
auto clk=clock();
#define y1 yyyyyy1
#define setb __builtin_popcount
#define BIT(n) (1<<(n))
#define SQR(x) ((x) * (x))
#define CUBE(x) ((x) * (x) * (x))
#define LSOne(S) (S) & (-S)
inline bool EQ(double a, double b) {return fabs(a - b) < 1e-9;}
 
typedef pair<int, int> ii;
typedef pair<int, ii> iii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef vector<string> vs;
 
template<typename T>inline T gcd(T a, T b){if (b == 0)return a;else return gcd(b, a % b);}
// template<typename T>inline T lcm(T a, T b){return (a * b) / gcd(a, b);}
template<typename T> string toStr(T x) {stringstream st; st << x; string s; st >> s; return s;}
template<class T>
void splitStr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}
 
inline int two(int n) {return 1 << n;}
inline int isOnBit(int n, int b) {return (n >> b) & 1;}
inline void onBit(int & n, int b) {n |= two(b);}
inline void offBit(int & n, int b) {n &= ~two(b);}
inline int lastBit(int n) {return n & (-n);}
inline int cntBit(int n) {int res = 0; while(n && ++res) n -= n &(-n); return res;}
 
const int dx4[] = {-1, 0, 1, 0};
const int dy4[] = {0, 1, 0, -1};
const int dx8[] = {-1, 0, 1, 0, -1, -1, 1, 1};
const int dy8[] = {0, 1, 0, -1, -1, 1, -1, 1};
 
#define INP "test.inp"
#define OUT "test.out"
 
#define PI 3.1415926535897932385
#define INF 10000000000000000ll
#define EPS 1e-7
#define MAXN 100000
#define MOD 1000000007ll
#define dec decr
#define endl '\n'
 
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ll gcd(ll a, ll b) 
{ 
    if (a == 0) 
        return b; 
    return gcd(b % a, a); 
} 
ll modexp(ll x, ll y, ll p)
{
    ll res = 1;   
    x = x % p;  
    while (y > 0)
    {
        if (y %2==1)    
            res = (res*x) % p;
        y = y>>1;     
        x = (x*x) % p; 
    }
    return res;
}
vector<pair<pair<ll,ll>,pair<ll,ll>>>adj[100005];
ll tim=0;
ll tin[100005];
ll tout[100005];
ll up[100005][20];
void dfs(ll x,ll p)
{
    tin[x]=tim++;
    up[x][0]=p;
    for(ll i=1;i<=19;i++)
    {
        up[x][i]=up[up[x][i-1]][i-1];
    }
    for(auto z:adj[x])
    {
        if(z.ff.ff!=p)
        {
            dfs(z.ff.ff,x);
        }
    }
    tout[x]=tim++;
}
bool isan(ll x,ll y)
{
    if(x==0)
    {
        return 1;
    }
    return tin[x]<=tin[y]&&tout[y]<=tout[x];
}
ll lca(ll x,ll y)
{
    if(isan(x,y))return x;
    if(isan(y,x))return y;
    for(ll i=19;i>=0;i--)
    {
        if(!isan(up[x][i],y))
        {
            x=up[x][i];
        }
    }
    return up[x][0];
}
vector<pair<ll,ll>>q[100005];
pair<ll,ll> ans[500005];
ll clr[100005];
ll cnt[100005];
ll val[100005];
void dfz(ll x,ll p)
{
    for(auto z:q[x])
    {
        auto xx=mp(clr[z.ss],cnt[z.ss]);
        ans[z.ff]=xx;
    }
    for(auto z:adj[x])
    {
        if(z.ff.ff!=p)
        {
            ll c=z.ss.ff;
            clr[c]+=z.ss.ss;
            cnt[c]++;
            val[z.ff.ff]=val[x]+z.ss.ss;
            dfz(z.ff.ff,x);
            clr[c]-=z.ss.ss;
            cnt[c]--;
        }
    }
}
int main () 
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout<<fixed;
    cout<<setprecision(9);
    #ifdef rg
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    ll n,m;
    cin>>n>>m;
    rep(i,n-1)
    {
        ll x,y,z,w;cin>>x>>y>>z>>w;
        adj[x].pb(mp(mp(y,i),mp(z,w)));
        adj[y].pb(mp(mp(x,i),mp(z,w)));
    }
    dfs(1,0);
    vector<pair<pair<ll,ll>,pair<ll,ll>>>qx;
    for(ll i=1;i<=m;i++)
    {
        ll x,y,z,w;
        cin>>z>>w>>x>>y;
        qx.pb(mp(mp(z,w),mp(x,y)));
        q[x].pb(mp(i*3+1,z));
        q[y].pb(mp(i*3+2,z));
        ll lc=lca(x,y);
        q[lc].pb(mp(i*3+3,z));
    }
    dfz(1,1);
    for(ll i=1;i<=m;i++)
    {
        ll a=ans[i*3+1].ff;
        a+=ans[i*3+2].ff;
        a-=2*ans[i*3+3].ff;
        ll b=ans[i*3+1].ss;
        b+=ans[i*3+2].ss;
        b-=2*ans[i*3+3].ss;
        // debug(a);
        // debug(b);
        auto x1=qx[i-1];
        ll z=x1.ff.ff;
        ll w=x1.ff.ss;
        ll x=x1.ss.ff;
        ll y=x1.ss.ss;
        ll lc=lca(x,y);
        ll an=val[x]+val[y]-2*val[lc]-a+b*w;
        cout<<an<<endl;
    }
    

    #ifdef rg
    cout<<endl<<endl<<"Time elapsed: "<<(double)(clock()-clk)/CLOCKS_PER_SEC<<endl;
    #endif
    return 0;
}   
                 

Measured memory_bytes: 54508