#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair< int , int > ii;
const int INF = 1e9 ;
const ll LINF = 1e18 ;
// - Nhận xét: dist(u, v, x, y) = dist(1, u, x, y) + dist(1, v, x, y) - 2 * dist(1, lca(u, v), x, y)
// => Với mọi truy vấn (u, v, x, y) ban đầu ta đều có thể biến đổi thành các truy vấn có dạng (1, i, x, y),
// và mỗi truy vấn (1, i, x, y) sẽ đi kèm với hệ số nhân thêm (coef) khi đóng góp vào đáp án của truy vấn ban đầu
// - Ngoài ra việc trả lời các truy vấn (1, i, x, y) cũng sẽ dễ dàng hơn, ta có thể thiết kế dfs sao cho khi dfs đến i thì ta cũng có được thông tin (cnt[c], sum[c]) của đường đi từ 1 đến i
const int N = 1e5 + 5 ;
const int Q = 1e5 + 5 ;
const int LOG = 17 ;
struct AdjEdge {
int to, c, w;
} ;
int n, q;
vector< AdjEdge> adj[ N] ;
ll dist[ N] ; // dist[u] = Khoảng cách từ 1 đến u ở cây ban đầu
int up[ LOG] [ N] ;
int tin[ N] , tout[ N] , timer;
void dfs1( int u, int p) {
tin[ u] = ++ timer;
up[ 0 ] [ u] = p;
for ( int i = 1 ; i < LOG; i++ ) {
up[ i] [ u] = up[ i - 1 ] [ up[ i - 1 ] [ u] ] ;
}
for ( auto e : adj[ u] ) {
int v = e.to ;
if ( v == p) continue ;
dist[ v] = dist[ u] + e.w ;
dfs1( v, u) ;
}
tout[ u] = timer;
}
bool isAncestor( int u, int v) {
return ( tin[ u] <= tin[ v] && tout[ v] <= tout[ u] ) ;
}
int lca( int u, int v) {
if ( isAncestor( u, v) ) return u;
if ( isAncestor( v, u) ) return v;
for ( int i = LOG - 1 ; i >= 0 ; i-- ) {
if ( ! isAncestor( up[ i] [ u] , v) ) {
u = up[ i] [ u] ;
}
}
return up[ 0 ] [ u] ;
}
struct Query {
int x, y, coef, idx;
} ;
vector< Query> queries[ N] ; // queries[u] = Danh sách các truy vấn ở đỉnh u
int cnt[ N] ; // cnt[c] = Số cạnh có màu c
ll sum[ N] ; // sum[c] = Tổng trọng số của những cạnh có màu c
ll ans[ Q] ; // ans[i] = Đáp án của truy vấn thứ i
void dfs2( int u, int p) {
// Khi dfs đến u thì ta có luôn thông tin của đường đi từ 1 đến u
for ( Query q : queries[ u] ) {
ans[ q.idx ] + = q.coef * ( dist[ u] - sum[ q.x ] + 1ll * cnt[ q.x ] * q.y ) ;
}
for ( auto & e : adj[ u] ) {
int v = e.to ;
if ( v == p) continue ;
// Thêm thông tin của cạnh (u, v) rồi sau đó gọi dfs vào v
cnt[ e.c ] ++ ;
sum[ e.c ] + = e.w ;
dfs2( v, u) ;
// Khi quay lui từ v lên u thì ta loại bỏ đi thông tin của cạnh (u, v)
cnt[ e.c ] -- ;
sum[ e.c ] - = e.w ;
}
}
int main( ) {
ios:: sync_with_stdio ( false ) ;
cin .tie ( nullptr) ;
cin >> n >> q;
for ( int i = 0 ; i < n - 1 ; i++ ) {
int u, v, c, w;
cin >> u >> v >> c >> w;
adj[ u] .push_back ( { v, c, w} ) ;
adj[ v] .push_back ( { u, c, w} ) ;
}
timer = 0 ;
dfs1( 1 , 1 ) ;
for ( int i = 0 ; i < q; i++ ) {
int x, y, u, v;
cin >> x >> y >> u >> v;
queries[ u] .push_back ( { x, y, 1 , i} ) ;
queries[ v] .push_back ( { x, y, 1 , i} ) ;
queries[ lca( u, v) ] .push_back ( { x, y, - 2 , i} ) ;
}
dfs2( 1 , 1 ) ;
for ( int i = 0 ; i < q; i++ ) {
cout << ans[ i] << '\n ' ;
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsgIAoKdHlwZWRlZiBsb25nIGxvbmcgbGw7ICAKdHlwZWRlZiBwYWlyPGludCwgaW50PiBpaTsgIAoKY29uc3QgaW50IElORiA9IDFlOTsgIApjb25zdCBsbCBMSU5GID0gMWUxODsgIAoKLy8gLSBOaOG6rW4geMOpdDogZGlzdCh1LCB2LCB4LCB5KSA9IGRpc3QoMSwgdSwgeCwgeSkgKyBkaXN0KDEsIHYsIHgsIHkpIC0gMiAqIGRpc3QoMSwgbGNhKHUsIHYpLCB4LCB5KQovLyA9PiBW4bubaSBt4buNaSB0cnV5IHbhuqVuICh1LCB2LCB4LCB5KSBiYW4gxJHhuqd1IHRhIMSR4buBdSBjw7MgdGjhu4MgYmnhur9uIMSR4buVaSB0aMOgbmggY8OhYyB0cnV5IHbhuqVuIGPDsyBk4bqhbmcgKDEsIGksIHgsIHkpLAovLyAgICB2w6AgbeG7l2kgdHJ1eSB24bqlbiAoMSwgaSwgeCwgeSkgc+G6vSDEkWkga8OobSB24bubaSBo4buHIHPhu5EgbmjDom4gdGjDqm0gKGNvZWYpIGtoaSDEkcOzbmcgZ8OzcCB2w6BvIMSRw6FwIMOhbiBj4bunYSB0cnV5IHbhuqVuIGJhbiDEkeG6p3UKLy8gLSBOZ2/DoGkgcmEgdmnhu4djIHRy4bqjIGzhu51pIGPDoWMgdHJ1eSB24bqlbiAoMSwgaSwgeCwgeSkgY8Wpbmcgc+G6vSBk4buFIGTDoG5nIGjGoW4sIHRhIGPDsyB0aOG7gyB0aGnhur90IGvhur8gZGZzIHNhbyBjaG8ga2hpIGRmcyDEkeG6v24gaSB0aMOsIHRhIGPFqW5nIGPDsyDEkcaw4bujYyB0aMO0bmcgdGluIChjbnRbY10sIHN1bVtjXSkgY+G7p2EgxJHGsOG7nW5nIMSRaSB04burIDEgxJHhur9uIGkKCmNvbnN0IGludCBOID0gMWU1ICsgNTsgCmNvbnN0IGludCBRID0gMWU1ICsgNTsgIApjb25zdCBpbnQgTE9HID0gMTc7ICAgCgpzdHJ1Y3QgQWRqRWRnZSB7CglpbnQgdG8sIGMsIHc7ICAKfTsgCgppbnQgbiwgcTsgIAp2ZWN0b3I8QWRqRWRnZT4gYWRqW05dOyAKCmxsIGRpc3RbTl07IC8vIGRpc3RbdV0gPSBLaG/huqNuZyBjw6FjaCB04burIDEgxJHhur9uIHUg4bufIGPDonkgYmFuIMSR4bqndQppbnQgdXBbTE9HXVtOXTsgCmludCB0aW5bTl0sIHRvdXRbTl0sIHRpbWVyOyAgCgp2b2lkIGRmczEoaW50IHUsIGludCBwKSB7Cgl0aW5bdV0gPSArK3RpbWVyOyAgCgl1cFswXVt1XSA9IHA7ICAgCglmb3IgKGludCBpID0gMTsgaSA8IExPRzsgaSsrKSB7CgkJdXBbaV1bdV0gPSB1cFtpIC0gMV1bdXBbaSAtIDFdW3VdXTsgCgl9Cglmb3IgKGF1dG8gZSA6IGFkalt1XSkgewoJCWludCB2ID0gZS50bzsgCgkJaWYgKHYgPT0gcCkgY29udGludWU7IAoJCWRpc3Rbdl0gPSBkaXN0W3VdICsgZS53OyAKCQlkZnMxKHYsIHUpOyAgCgl9Cgl0b3V0W3VdID0gdGltZXI7IAp9Cgpib29sIGlzQW5jZXN0b3IoaW50IHUsIGludCB2KSB7CglyZXR1cm4gKHRpblt1XSA8PSB0aW5bdl0gJiYgdG91dFt2XSA8PSB0b3V0W3VdKTsgCn0KCmludCBsY2EoaW50IHUsIGludCB2KSB7CglpZiAoaXNBbmNlc3Rvcih1LCB2KSkgcmV0dXJuIHU7IAoJaWYgKGlzQW5jZXN0b3IodiwgdSkpIHJldHVybiB2OyAgCglmb3IgKGludCBpID0gTE9HIC0gMTsgaSA+PSAwOyBpLS0pIHsKCQlpZiAoIWlzQW5jZXN0b3IodXBbaV1bdV0sIHYpKSB7CgkJCXUgPSB1cFtpXVt1XTsgCgkJfQoJfQoJcmV0dXJuIHVwWzBdW3VdOyAKfQoKc3RydWN0IFF1ZXJ5IHsKCWludCB4LCB5LCBjb2VmLCBpZHg7ICAKfTsgCgp2ZWN0b3I8UXVlcnk+IHF1ZXJpZXNbTl07IC8vIHF1ZXJpZXNbdV0gPSBEYW5oIHPDoWNoIGPDoWMgdHJ1eSB24bqlbiDhu58gxJHhu4luaCB1ICAKaW50IGNudFtOXTsgLy8gY250W2NdID0gU+G7kSBj4bqhbmggY8OzIG3DoHUgYwpsbCBzdW1bTl07IC8vIHN1bVtjXSA9IFThu5VuZyB0cuG7jW5nIHPhu5EgY+G7p2Egbmjhu69uZyBj4bqhbmggY8OzIG3DoHUgYwpsbCBhbnNbUV07IC8vIGFuc1tpXSA9IMSQw6FwIMOhbiBj4bunYSB0cnV5IHbhuqVuIHRo4bupIGkgCgp2b2lkIGRmczIoaW50IHUsIGludCBwKSB7CgkvLyBLaGkgZGZzIMSR4bq/biB1IHRow6wgdGEgY8OzIGx1w7RuIHRow7RuZyB0aW4gY+G7p2EgxJHGsOG7nW5nIMSRaSB04burIDEgxJHhur9uIHUgCglmb3IgKFF1ZXJ5IHEgOiBxdWVyaWVzW3VdKSB7CgkJYW5zW3EuaWR4XSArPSBxLmNvZWYgKiAoZGlzdFt1XSAtIHN1bVtxLnhdICsgMWxsICogY250W3EueF0gKiBxLnkpOyAKCX0KCglmb3IgKGF1dG8gJmUgOiBhZGpbdV0pIHsKCQlpbnQgdiA9IGUudG87ICAKCQlpZiAodiA9PSBwKSBjb250aW51ZTsgCgkJLy8gVGjDqm0gdGjDtG5nIHRpbiBj4bunYSBj4bqhbmggKHUsIHYpIHLhu5NpIHNhdSDEkcOzIGfhu41pIGRmcyB2w6BvIHYKCQljbnRbZS5jXSsrOyAgCgkJc3VtW2UuY10gKz0gZS53OyAKCQlkZnMyKHYsIHUpOyAKCQkvLyBLaGkgcXVheSBsdWkgdOG7qyB2IGzDqm4gdSB0aMOsIHRhIGxv4bqhaSBi4buPIMSRaSB0aMO0bmcgdGluIGPhu6dhIGPhuqFuaCAodSwgdikKCQljbnRbZS5jXS0tOyAKCQlzdW1bZS5jXSAtPSBlLnc7IAoJfQp9CgppbnQgbWFpbigpIHsKCWlvczo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsgCgljaW4udGllKG51bGxwdHIpOyAJCgljaW4gPj4gbiA+PiBxOyAKCWZvciAoaW50IGkgPSAwOyBpIDwgbiAtIDE7IGkrKykgewoJCWludCB1LCB2LCBjLCB3OyAgCgkJY2luID4+IHUgPj4gdiA+PiBjID4+IHc7IAoJCWFkalt1XS5wdXNoX2JhY2soe3YsIGMsIHd9KTsgCgkJYWRqW3ZdLnB1c2hfYmFjayh7dSwgYywgd30pOyAKCX0KCgl0aW1lciA9IDA7IAoJZGZzMSgxLCAxKTsgCgoJZm9yIChpbnQgaSA9IDA7IGkgPCBxOyBpKyspIHsKCQlpbnQgeCwgeSwgdSwgdjsgCgkJY2luID4+IHggPj4geSA+PiB1ID4+IHY7IAoJCXF1ZXJpZXNbdV0ucHVzaF9iYWNrKHt4LCB5LCAxLCBpfSk7CgkJcXVlcmllc1t2XS5wdXNoX2JhY2soe3gsIHksIDEsIGl9KTsKCQlxdWVyaWVzW2xjYSh1LCB2KV0ucHVzaF9iYWNrKHt4LCB5LCAtMiwgaX0pOyAKCX0KCglkZnMyKDEsIDEpOyAgCgoJZm9yIChpbnQgaSA9IDA7IGkgPCBxOyBpKyspIHsKCQljb3V0IDw8IGFuc1tpXSA8PCAnXG4nOyAKCX0KfQ==