#include<bits/stdc++.h>
#include "virus.h"
#define rep(i,l,r) for (int i(l), i##end(r); i <= i##end; ++i)
#define per(i,r,l) for (int i(r), i##end(l); i >= i##end; --i)
#define LL long long
#define eb emplace_back
#define PII pair <LL, int>
using namespace std;
const int N = 1e5 + 9;
int n, m, num, all, mn, rt;
int fa[N], in[N], out[N], C[N], sz[N], mxsz[N], vis[N];
vector <int> G[N], dis[N];
const int LogN = 20;
const int Pt = 2 * N * LogN;
vector <pair <int, int> > edge[Pt];
LL dist[Pt];
void cmax(int &a, int b) {a < b && (a = b);}
int ecnt;
void add_edge(int u, int v, int l) {
++ecnt;
edge[u].eb(v, l);
}
void add_edge(int u, int v) {
G[u].eb(v), G[v].eb(u);
}
void getsz(int u, int lst) {
sz[u] = 1, mxsz[u] = 0;
for (int v : G[u]) if (v != lst && !vis[v]) {
getsz(v, u);
cmax(mxsz[u], sz[v]);
sz[u] += sz[v];
}
cmax(mxsz[u], all - sz[u]);
if (mxsz[u] < mn) mn = mxsz[u], rt = u;
}
vector <int> vert_in[N], vert_out[N];
int cur;
void getdis(int u, int d, int lst) {
add_edge(vert_in[cur][d], in[u], 0);
add_edge(out[u], vert_out[cur][d], 0);
dis[u].eb(d);
for (int v : G[u]) if (v != lst && !vis[v]) {
getdis(v, d + 1, u);
}
}
void build(int u) {
vis[u] = 1;
getsz(u, -1);
vert_in[u].resize(sz[u]);
vert_out[u].resize(sz[u]);
for (int &v : vert_in[u]) v = ++num;
for (int &v : vert_out[u]) v = ++num;
rep (i, 0, sz[u] - 2) {
add_edge(vert_in[u][i + 1], vert_in[u][i], 0);
add_edge(vert_out[u][i], vert_out[u][i + 1], 0);
}
cur = u;
getdis(u, 0, -1);
for (int v : G[u]) if (!vis[v]) {
rt = -1, mn = 1e9, all = sz[v];
getsz(v, u); fa[rt] = u;
build(rt);
}
}
int id[N];
priority_queue <PII, vector <PII>, greater<PII> > pq;
vector<long long> find_spread(int N, int M, vector<int> A, vector<int> B, vector<int> P, vector<int> D, vector<int> C) {
n = N;
m = M;
for (int i = 0, u, v; i < n - 1; ++i) {
u = A[i], v = B[i];
add_edge(u, v);
}
rep (i, 0, n - 1) in[i] = ++num, out[i] = ++num;
rt = -1, mn = 1e9, all = n;
getsz(0, -1);
fa[rt] = -1;
build(rt);
rep (i, 0, m - 1) {
int p, d; p = P[i], d= D[i];
id[i] = ++num;
for (int x = p, j = dis[p].size() - 1; ~x; x = fa[x], --j) {
int dt = min(d - dis[p][j], sz[x] - 1);
if (dt < 0) continue;
add_edge(id[i], vert_in[x][dt], 0);
add_edge(vert_out[x][dt], id[i], 0);
}
}
rep (i, 0, n - 1) add_edge(in[i], out[i], C[i]);
memset(dist, 0x3f, sizeof(dist));
dist[id[0]] = 0; pq.push({dist[id[0]], id[0]});
while (!pq.empty()) {
PII top = pq.top(); pq.pop();
if (dist[top.second] != top.first) continue;
int u = top.second;
for (auto [v, l] : edge[u]) {
if (dist[u] + l < dist[v]) {
dist[v] = dist[u] + l;
pq.push({dist[v], v});
}
}
}
vector <LL> ans(m);
rep (i, 0, m - 1) ans[i] = dist[id[i]] == dist[0] ? -1 : dist[id[i]];
return ans;
}