#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;
int N,Q,M;
//const LL  INF  = 0x3f3f3f3f3f3f3f3f;
const int inf  = 0x3f3f3f3f;

const int maxn = 1e5+5;

struct Edge{
    int u,v;
    LL c,d;
    Edge(int u = 0,int v = 0,LL c = 0,LL d = 0):u(u),v(v),c(c),d(d){;}
    bool operator<(const Edge &e){return c < e.c;}
};

struct P{
    int num;
    LL dis;
    P(int num = 0,LL dis = 0):num(num),dis(dis){;}
};

struct Query{
    int a,b,c,d,f;
    Query(int a,int b,int c,int d,int f):a(a),b(b),c(c),d(d),f(f){;}

};

int cnt = 0;

set<int> mp[maxn];
vector<int> G[maxn];
vector<Edge> edges;
vector<Query> ques;
map<LL,pll> kk;

map<int,P> G2[maxn];

bool vis[maxn];
int deep[maxn];
int fa[maxn][25];

LL dis[maxn];

void searching(int u,int f,LL d){
    dis[u] = d;
    for(auto a: mp[u]){
        if(!kk.count(a)){
            G2[u][a] = P(0,0);
        }else{
            G2[u][a] = P(kk[a].second,kk[a].first);
        }
    }
    for(int a:G[u]){
        Edge e = edges[a];
        if(e.v == f) continue;

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

        if(!kk.count(e.c)) kk[e.c] = MP(e.d,1);
        else{
            pll &nex = kk[e.c];
            nex.first += e.d;
            nex.second++;
        }
        searching(e.v,u,d + e.d);
        pll &nex = kk[e.c];
        nex.first -= e.d;
        nex.second--;
    }
}


void dfs(int u,int f)
{
    vis[u] = true;

    for(auto a:G[u])
    {
        int v = edges[a].v;
        if(!vis[v])
        {
            deep[v] = deep[u] + 1;
            fa[v][0] = u;
            dfs(v,u);
        }
    }
}

void bz()  // 倍增祖先
{
    int j ;
    for(j = 1 ; j < M ; j++)
    {
        _rep(i, 1 ,N)
        {
            fa[i][j] = fa[ fa[i][j - 1] ][j - 1] ;
        }
    }
}

int LCA(int u , int v)
{
    if(deep[u] < deep[v]) swap(u , v);
    int dd = deep[u] - deep[v] ;

    _for(i,0,M){
        if( (1 << i) & dd)  // 注意此处，动手模拟一下，就会明白的
        {
            u = fa[u][i] ;
        }
    }

    if(u == v) return u;

    for(int i = M - 1 ; i >= 0 ; i--)
    {
        if(fa[u][i] != fa[v][i])
        {
            u = fa[u][i] ;
            v = fa[v][i] ;
        }
    }

    u = fa[u][0];
    return u;
}
void init()
{
    MEM(vis ,0);
    MEM(deep ,0);
    MEM(fa , 0);

    int root = 1;
    deep[root] = 1;
    fa[root][0] = 1;

    dfs(root,root);

    bz();
}




int main()
{
    cin >> N >> Q;
    M = 24;

    _for(i,0,N-1){
        int a,b,c,d;
        cin >> a >> b >> c >> d;

        edges.PB(Edge(a,b,c,d));
        edges.PB(Edge(b,a,c,d));
        G[a].PB(edges.size() - 2);
        G[b].PB(edges.size() - 1);

    }

    init();


    _for(j,0,Q){
        int a,b,c,d;
        cin >> c >> d >> a >> b;
        mp[a].insert(c);
        mp[b].insert(c);
        int f = LCA(a,b);
        mp[f].insert(c);
        ques.PB(Query(a,b,c,d,f));
    }

    searching(1,-1,0);



    _for(j,0,Q){
        LL a,b,c,d,f;
        Query q = ques[j];
        a = q.a;
        b = q.b;
        c = q.c;
        d = q.d;
        f = q.f;

        LL ans = dis[a] + dis[b] - 2*dis[f];

        LL dis_bef = G2[a][c].dis + G2[b][c].dis - 2*G2[f][c].dis;
        //cout << dis_bef << endl;

        LL num = G2[a][c].num + G2[b][c].num - 2*G2[f][c].num;

        //cout << num <<endl;

        ans = ans - dis_bef + num*d;
        cout << ans << endl;
    }
    return 0;
}


Measured memory_bytes: 69420