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

#define ff first
#define sc second
#define ll long long
#define pb push_back
#define all(x) (x).begin(),(x).end()

const int maxN = 2 * 1e5;

vector<ll> d;
vector<bool> f;
vector<int> g[maxN], s, t;
int n, m, par[maxN][20], dep[maxN], in[maxN], out[maxN], tim;
void dfs(int v, int p) {
    in[v] = ++tim;
    par[v][0] = p; dep[v] = dep[p] + 1;
    for (int u : g[v]) {
        if (u == p) continue;
        dfs(u, v);
    }

    out[v] = ++tim;
}

bool is_anc(int x, int y) {
    return (in[x] <= in[y] && out[x] >= out[y]);
}
int lca(int x, int y) {
    if (is_anc(x, y)) return x;
    if (is_anc(y, x)) return y;
    for (int j = 19; j >= 0; j--) {
        if (!is_anc(par[x][j], y)) x = par[x][j];
    } return par[x][0];
}
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> _f
) {

    for (auto i : r) {
        g[i.ff].pb(i.sc);
        g[i.sc].pb(i.ff);
    }

    d = _d; s = _s; t = _t; f = _f;
    n = (int)r.size() + 1; m = (int)d.size();

    dfs(0, 0);
    for (int j = 1; j < 20; j++) {
        for (int i = 0; i < n; i++) {
            par[i][j] = par[par[i][j - 1]][j - 1];
        }
    }

    set<int> inf[n], good[n];
    vector<int> ans(m, -1), pat[m], nxt[m];
    for (int i = 0; i < m; i++) {
        if (f[i] == 1) ans[i] = 0;
        int lc = lca(s[i], t[i]);

        int x = s[i];
        while (x != lc) {
            pat[i].pb(x); x = par[x][0];
        }

        vector<int> tmp; x = t[i];
        while (x != lc) {
            tmp.pb(x); x = par[x][0];
        } tmp.pb(lc); reverse(all(tmp));

        for (int j : tmp) pat[i].pb(j);

        nxt[i].resize(pat[i].size());
        for (int j = 0; j + 1 < pat[i].size(); j++)
            nxt[i][j] = pat[i][j + 1];
        nxt[i].back() = -1;

        if (f[i] == 0) good[s[i]].insert(i);
        else inf[s[i]].insert(i);
    }

    for (int i = 0; i <= n; i++) {
        for (int j = 0; j < n; j++) {
            if (good[j].size() && inf[j].size()) {
                for (int k : good[j]) {
                    ans[k] = i; inf[j].insert(k);
                } good[j].clear();
            }
        }


        for (int j = 0; j < m; j++) {
            if (pat[j].size() <= i) continue;

            inf[pat[j][i]].erase(j);
            good[pat[j][i]].erase(j);
            if (nxt[j][i] != -1) {
                if (ans[j] != -1) inf[nxt[j][i]].insert(j);
                else good[nxt[j][i]].insert(j);
            }
        }
    }

    for (int i = 0; i < m; i++) {
        if (ans[i] == -1) ans[i] = 0;
        else ans[i] = (int)pat[i].size() - ans[i];
    }

    return ans;
}


// signed main() {
//     int n, m;

//     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;
// }
