#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include<bits/stdc++.h>
#define F first
#define S second
#define vec vector
#define ms multiset
#define pb push_back
#define pll pair<ll,ll>
#define pdd pair<ld, ld>
#define pq priority_queue
#define umap unordered_map
#define uset unordered_set
#define pii pair<int, int>
#define pnn pair<Node*, Node*>
#define uid uniform_int_distribution
#define FILE ifstream in("board.in");ofstream out("board.out");
#define fast cin.tie(0);cout.tie(0);cin.sync_with_stdio(0);cout.sync_with_stdio(0);
using namespace std;
typedef string str;
typedef long long ll;
typedef long double ld;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); //uid<int> u1(5, 10); u1(rnd);

struct edg{
    int y,c,d;
    edg(int a, int b, int cc){
        y = a;
        c = b;
        d = cc;
    }
};

struct Node{
    Node *l, *r;
    pii p;

    Node(Node *a, Node *b){
        l = a; r = b;
        p = {a->p.F+b->p.F, a->p.S+b->p.S};
    }

    Node(Node *a, Node *b, pii pp){
        l = a; r = b;
        p = pp;
    }

    Node(Node *n){
        l = n->l; r = n->r;
        p = n->p;
    }
};

Node* add(int l, int r, int pos, Node *n, int val){
    Node *cp = n ? new Node(n) : new Node(0,0,{0,0});
    if(l==r){
        cp->p.F++;
        cp->p.S += val;
        return cp;
    }
    int md = (l+r)/2;
    if(pos<=md) cp->l = add(l,md,pos,cp->l,val);
    else cp->r = add(md+1,r,pos,cp->r,val);
    return cp;
}

pii get(int l, int r, int pos, Node *n){
    if(!n) return {0,0};
    if(l==r) return n->p;
    int md = (l+r)/2;
    if(pos<=md) return get(l,md,pos,n->l);
    else return get(md+1,r,pos,n->r);
}

int a, z, SIZE = 1e5+5;
vec<vec<edg>> l;
vec<vec<int>> n;
vec<int> cl, dl, prs, dep, mx;
vec<Node*> m;

void init(int v, int pr, int c, int d, int depp){
    cl[v] = c;
    dl[v] = d;
    dep[v] = depp;
    n[0][v] = pr;
    if(pr!=-1){
        m[v] = add(0, SIZE, c, m[pr], d);
        prs[v] = prs[pr]+d;
    }
    for(edg h : l[v]){
        if(h.y==pr) continue;
        init(h.y, v, h.c, h.d, depp+1);
    }
}

int lca(int x, int y){
    if(dep[x]>dep[y]) swap(x,y);
    for(int d=dep[y]-dep[x]; d; d-=1<<mx[d]) y = n[mx[d]][y];
    for(int q=16; x!=y && q>=0; q--){
        int px = n[q][x], py = n[q][y];
        if(px!=py || q==0) x = px, y = py;
    }
    return x==y ? x : n[0][x];
}

int main() {
    fast;
    mx = vec<int>(SIZE);
    for(int q=2; q<SIZE; q++) mx[q] = 2<<mx[q-1]>q ? mx[q-1] : mx[q-1]+1;
    cin>>a>>z;
    m = vec<Node*>(a);
    dep = vec<int>(a);
    cl = vec<int>(a);
    dl = vec<int>(a);
    prs = vec<int>(a);
    n = vec<vec<int>>(17, vec<int>(a));
    l = vec<vec<edg>>(a, vec<edg>());
    for(int q=0; q<a-1; q++){
        int x,y,c,d; cin>>x>>y>>c>>d; x--; y--;
        l[x].pb(edg(y,c,d));
        l[y].pb(edg(x,c,d));
    }
    m[0] = new Node(0,0,{0,0});
    init(0,-1,0,0,0);
    for(int q=1; q<17; q++){
        for(int w=0; w<a; w++){
            n[q][w] = n[q-1][w]==-1 ? -1 : n[q-1][n[q-1][w]];
        }
    }
    for(; z; z--){
        int x,y,c,d; cin>>c>>d>>x>>y; x--; y--;
        int lc = lca(x,y);
        int sum = prs[x] + prs[y] - 2*prs[lc];
        pii px = get(0, SIZE, c, m[x]);
        pii py = get(0, SIZE, c, m[y]);
        pii pl = get(0, SIZE, c, m[lc]);
        pii po = {px.F+py.F-2*pl.F, px.S+py.S-2*pl.S};
        cout<<sum-po.S+po.F*d<<"\n";
    }
}

Measured memory_bytes: 77816