#include <bits/stdc++.h>

using namespace std;
#define _for(i,j,N) for(int i = (j);i < (N);i++)
#define _rep(i,j,N) for(int i = (j);i <= (N);i++)
#define _dec(i,N,j) for(int i = (N-1);i >= (j);i--)
#define _rec(i,N,j) for(int i = (N);i >=(j);i--)
#define ALL(x) x.begin(),x.end()
#define MEM(a,n) memset(a,n,sizeof(a))
#define fst first
#define scd second
#define PB push_back
#define MP make_pair

typedef long long LL;
typedef long double LD;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

int get_int(){int x;scanf("%d",&x);return x;}
LL get_ll(){LL x;scanf("%lld",&x);return x;}
double get_db(){double x;scanf("%lf",&x);return x;}

template<typename T> int chmin(T &a,T b){if(a > b){a = b;return 1;}else return 0;}
template<typename T> int chmax(T &a,T b){if(a < b){a = b;return 1;}else return 0;}
template<typename T>
ostream& operator<<(ostream& os,const vector<T>& v) {_for(i,0,v.size()) os << v[i] << " ";return os;}
template<typename T>
ostream& operator<<(ostream& os,const set<T>& v){for(auto a:v) os << a <<" ";return os;}
template<typename T1,typename T2>
ostream& operator<<(ostream& os,const pair<T1,T2>& v){os << v.fst <<" "<<v.scd << " ";return os;}
template<typename T1,typename T2>
ostream& operator<<(ostream& os,const map<T1,T2>& v){for(auto a:v) cout << a << endl;return os;}

static const int dx[8] = { -1,  0, 1, 0,  1, -1,  1, -1};
static const int dy[8] = {0,  1, 0,  -1,  1, -1, -1,  1};
const double pi  = acos(-1.0);
const double eps = 1e-8;
//const LL  INF  = 0x3f3f3f3f3f3f3f3f;
const int inf  = 0x3f3f3f3f;

const int maxn = 1e5+5;

struct Edge{
    int u,v,c;
    LL d;
    Edge(int u,int v,int c,LL d):u(u),v(v),c(c),d(d){;}
};

LL disu[maxn];LL disv[maxn];
LL cnumu[maxn];LL cnumv[maxn];
LL lengthu[maxn];LL lengthv[maxn];

LL qy[maxn];LL qc[maxn];
LL ans[maxn];

LL d[maxn];
LL path[maxn][2];// 0 is number ,1 is length.
int vis[maxn];

vector<int> G[maxn];
vector<Edge> edges;

vector<pii> QS[maxn];// first is node , second is qnum.
vector<int> Qan[maxn];

int f[maxn];
int finds(int x){return (x == f[x])?x:(f[x] = finds(f[x]));}
void connect(int x,int y){
    int fx = finds(x);
    int fy = finds(y);
    f[fx] = fy;
}//x connect to y/

int N,Q;

void init(){
    _for(i,0,maxn) f[i] = i;
    cin >> N >> Q;
    _for(i,1,N){
        int a,b,c;
        LL d;
        cin >> a >> b >> c >> d;
        Edge e(a,b,c,d);
        G[a].push_back(edges.size());
        G[b].push_back(edges.size());
        edges.PB(e);
    }
    _for(i,0,Q){
        int x , y , u , v;
        cin >> x >> y >> u >> v;
        QS[u].PB(MP(v,i));
        QS[v].PB(MP(u,i));
        qy[i] = y;
        qc[i] = x;
    }
    memset(vis,0,sizeof(vis));
    memset(d,0,sizeof(d));
    memset(path,0,sizeof(path));
    memset(disu,-1,sizeof(disu));
}

void tarjan(int u,int p){
    vis[u] = 1;
    for(int a : G[u]){
        Edge e = edges[a];
        int v = (e.u == u? e.v : e.u);

        //cout << e.v << endl;

        if(v != p){
            d[v] = d[u] + e.d;
            path[e.c][0]++;
            path[e.c][1] += e.d;
            tarjan(v,u);
            path[e.c][0]--;
            path[e.c][1] -= e.d;
            connect(v,u);
        }
    }


    //cout <<" u: " << u << endl;
    for(pii a:QS[u]){
        int v = a.first;
        int qnum = a.second;
        //cout << qnum << endl;
        int c = qc[qnum];
        if(vis[v]){
            //cout <<qnum << endl;
            int fa = finds(v);

            Qan[fa].PB(qnum);
        }

        if(disu[qnum] == -1){
            disu[qnum] = d[u];
            cnumu[qnum] = path[c][0];
            lengthu[qnum] = path[c][1];
        }
        else{
            disv[qnum] = d[u];
            cnumv[qnum] = path[c][0];
            lengthv[qnum] = path[c][1];
        }
    }

    for(int qnum:Qan[u]){
        //cout <<qnum << endl;
        int c = qc[qnum];
        LL dis_ance = d[u];
        LL cnum_ance = path[c][0];
        LL length_ance = path[c][1];

        ans[qnum] = disu[qnum] + disv[qnum] - 2 * dis_ance;
        ans[qnum] += (cnumu[qnum] + cnumv[qnum] - 2 * cnum_ance) * qy[qnum];
        ans[qnum] -= (lengthu[qnum] + lengthv[qnum] - 2*length_ance);
    }

}





int main()
{
    init();
    tarjan(1,0);
    _for(i,0,Q) cout << ans[i] << endl;

    return 0;
}


Measured memory_bytes: 36272