#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;

using namespace __gnu_pbds;

const int N = 2e5;
vector<int> g[N];
int tin[N], tout[N];
int up[20][N];
//#define int long long
int t;
int depth[N];
void precalc (int v, int p = 0) {
    tin[v] = t++;
    up[0][v] = p;
    depth[v] = depth[p] + 1;
    for (int l = 1; l < 20; ++l) up[l][v] = up[l - 1][up[l - 1][v]];
    for (auto to : g[v]) {
        if (to != p) precalc (to, v);
    }
    tout[v] = t;
}
bool is_anc (int u, int v) {
    return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int lca (int u, int v) {
    if (is_anc (u, v)) return u;
    if (is_anc (v, u)) return v;
    for (int l = 19; l >= 0; --l) {
        if (!is_anc (up[l][u], v)) u = up[l][u];
    }
    return up[0][u];
}
vector<int> getpath (int u, int v) {
    if (u == v) return {u};
    vector<int> path;
    if (is_anc (u, v)) {
        while (v != u) {
            path.push_back(v);
            v = up[0][v];
        }
        path.push_back(u);
        reverse(begin (path), end (path));
        return path;
    }
    if (is_anc (v, u)) {
        while (v != u) {
            path.push_back(u);
            u = up[0][u];
        }
        path.push_back(v);
        return path;

    }
    while (!is_anc (u, v)) {
        path.push_back(u);
        u = up[0][u];
    }
    path.push_back(u);
    swap (u, v);
    vector<int> p2;
    while (!is_anc (u, v)) {
        p2.push_back(u);
        u = up[0][u];
    }
    reverse(begin (p2), end (p2));
    for (auto it : p2) path.push_back(it);
    return path;
}
int dist (int u, int v) {
    return depth[u] + depth[v] - 2 * depth[lca (u, v)] + 1;
}
unordered_map<int,long long> IS[5001];
vector<pair<int,long long>> nG[N];
std::vector<int> solve(
std::vector<std::pair<int, int>> R,
std::vector<long long> D,
std::vector<int> S,
std::vector<int> T,
std::vector<bool> I) {
    int n = (int)R.size() + 1, m = (int)I.size();
    for (auto [u, v] : R) g[u].push_back (v), g[v].push_back (u);
    precalc (0);
    vector<int> F(m);
    for (int i = 0; i < m; ++i) {
        vector<int> P = getpath(S[i], T[i]);
        F[i] = (int)P.size();
        for (int j = 0; j < (int)P.size(); ++j) {
            if (IS[P[j]].find (D[i] + j) == IS[P[j]].end()) {
                IS[P[j]][D[i] + j] = i;
            } else {
                nG[i].push_back ({IS[P[j]][D[i] + j], D[i] + j});
                nG[IS[P[j]][D[i] + j]].push_back ({i, D[i] + j});

                IS[P[j]][D[i] + j] = i;
            }
        }
    }
    vector<long long> dists (m + 1, 1e18);
    set<pair<int, long long>> St;
    for (int i = 0; i < m; ++i) {
        if (I[i]) {
            St.insert ({D[i], i});
            dists[i] = D[i];
        }
    }
    while ((int)St.size()) {
        int v = (*St.begin()).second;
        St.erase (St.begin());
        for (auto [to, w] : nG[v]) {
            if (w >= dists[v] &&
                w < dists[to]) {
                St.erase ({dists[to], to});
                dists[to] = max (dists[v], w);
                St.insert ({dists[to], to});
            }
        }
    }

    vector<int> ans(m);
    for (int i = 0; i < m; ++i) {
        if (dists[i] == 1e18) ans[i] = 0;
        else ans[i] = max (0, (int) (F[i] + D[i] - dists[i]));
    }
    return ans;
};

#ifdef LOCAL
//#include "infection.h"
#include <vector>
#include <iostream>

signed main() {
    int n, m;
    freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
    std::cin >> n;
    std::cin >> m;

    std::vector<std::pair<int, int>> edges = {};
    std::vector<long long> day;
    std::vector<int> start;
    std::vector<int> target;
    std::vector<bool> infected;

    for (int i = 0; i < n - 1; i++) {
        int u, v;
        std::cin >> u >> v;
        edges.emplace_back(u, v);
    }

    for (int i = 0; i < m; i++) {
        long long _d, _s, _t, _i;
        std::cin >> _d >> _s >> _t >> _i;
        day.push_back(_d);
        start.push_back(_s);
        target.push_back(_t);
        infected.push_back(_i);
    }

    const auto ans = solve(edges, day, start, target, infected);
    for (const auto it : ans) {
        std::cout << it << std::endl;
    }

    return 0;
}

#endif // LOCAL
