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

template<typename Tp>
class disjoint_sparse_table{
    size_t n;
    vector<int> row;
    vector<Tp> table;
    Tp (*operation)(Tp, Tp);
public:
    disjoint_sparse_table(vector<Tp> _values, Tp (*_operation)(Tp, Tp))
    : table(_values), operation(_operation){
        n = _values.size();
        int depth = 0;
        row.push_back(0);
        for(size_t m=1;m<n;m<<=1){
            for(size_t i=m;i<2*m;++i) row.push_back(depth);
            ++depth;
        }
        
        table.resize(n * depth);

        for(int d=1;d<depth;++d){
            int w = 1 << d;
            size_t pos = 0;
            
            while(pos + w < n){
                table[d*n + pos+w-1] = table[pos+w-1];
                for(int i=w-2;i>=0;--i) table[d*n + pos+i] = operation(table[pos+i], table[d*n + pos+i+1]);
                pos += w;
                if(pos < n) table[d*n + pos] = table[pos];
                for(int i=1;pos+i<n && i<w;++i) table[d*n + pos+i] = operation(table[d*n + pos+i-1], table[pos+i]);
                pos += w;
            }
        }
    }

    Tp get(size_t left, size_t right){
        if(left == right) return table[left];
        return operation(table[row[left^right]*n + left], table[row[left^right]*n + right]);
    }

    Tp operator[](size_t pos){
        return table[pos];
    }
};

int main(){
    int n, q;
    cin >> n >> q;
    vector<pair<int,pair<int,int>>> edges[100001]; // {to, {color, length}}
    for(int i=0;i<n-1;++i){
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        edges[a].push_back({b, {c, d}});
        edges[b].push_back({a, {c, d}});
    }
    int idx_v[100001], idx_e[100001];
    vector<pair<int,int>> euler_tour_v, euler_tour_e;
    vector<pair<int,int>> col_len[100001], col_cnt[100001];
    for(int c=1;c<=n;++c){
        col_len[c].emplace_back(-1, 0);
        col_cnt[c].emplace_back(-1, 0);
    }

    auto dfs_v = [&](auto f, int v, int p, int level) -> void{
        idx_v[v] = euler_tour_v.size();
        euler_tour_v.emplace_back(v, level);
        for(auto to: edges[v]){
            if(to.first != p) f(f, to.first, v, level+1);
            euler_tour_v.emplace_back(v, level);
        }
    };
    dfs_v(dfs_v, 1, 0, 0);
    auto dfs_e = [&](auto f, int v, int p) -> void{
        for(auto to: edges[v]){
            if(to.first == p) continue;
            idx_e[to.first] = euler_tour_e.size();
            col_len[to.second.first].emplace_back(euler_tour_e.size(), to.second.second);
            col_cnt[to.second.first].emplace_back(euler_tour_e.size(), 1);
            euler_tour_e.emplace_back(to.first, to.second.second);
            f(f, to.first, v);
            col_len[to.second.first].emplace_back(euler_tour_e.size(), -to.second.second);
            col_cnt[to.second.first].emplace_back(euler_tour_e.size(), -1);
            euler_tour_e.emplace_back(-to.first, -to.second.second);
        }
    };
    dfs_e(dfs_e, 1, 0);
    disjoint_sparse_table<pair<int,int>> lca {
        euler_tour_v,
        [](auto lhs, auto rhs){
            return lhs.second < rhs.second ? lhs : rhs;
        }
    };
    disjoint_sparse_table<pair<int,int>> dist{
        euler_tour_e,
        [](auto lhs, auto rhs) -> pair<int,int>{
            return {0, lhs.second + rhs.second};
        }
    };
    for(int c=0;c<n;++c){
        for(int i=1;i<col_len[c].size();++i){
            col_len[c][i].second += col_len[c][i-1].second;
            col_cnt[c][i].second += col_cnt[c][i-1].second;
        }
    }

    for(int i=0;i<q;++i){
        int x, y, u, v;
        cin >> x >> y >> u >> v;
        auto a = lca.get(min(idx_v[u], idx_v[v]), max(idx_v[u], idx_v[v])).first;
        int da = a==1 ? 0 : dist.get(0, idx_e[a]).second;
        int du = u==1 ? 0 : dist.get(0, idx_e[u]).second;
        int dv = v==1 ? 0 : dist.get(0, idx_e[v]).second;
        int la = a==1 ? 0 : prev(lower_bound(col_len[x].begin(), col_len[x].end(), pair<int,int>{idx_e[a], INT32_MAX}))->second;
        int lu = u==1 ? 0 : prev(lower_bound(col_len[x].begin(), col_len[x].end(), pair<int,int>{idx_e[u], INT32_MAX}))->second;
        int lv = v==1 ? 0 : prev(lower_bound(col_len[x].begin(), col_len[x].end(), pair<int,int>{idx_e[v], INT32_MAX}))->second;
        int ca = a==1 ? 0 : prev(lower_bound(col_cnt[x].begin(), col_cnt[x].end(), pair<int,int>{idx_e[a], INT32_MAX}))->second;
        int cu = u==1 ? 0 : prev(lower_bound(col_cnt[x].begin(), col_cnt[x].end(), pair<int,int>{idx_e[u], INT32_MAX}))->second;
        int cv = v==1 ? 0 : prev(lower_bound(col_cnt[x].begin(), col_cnt[x].end(), pair<int,int>{idx_e[v], INT32_MAX}))->second;
        
        cout << (du+dv-2*da) - (lu+lv-2*la) + y*(cu+cv-2*ca) << endl;
    }
    
    return 0;
}

Measured memory_bytes: 114208