#include using namespace std; #define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__) #define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__) #define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name #define REP1(n) for(ll i=0;i<(n);i++) #define REP2(i, n) for (ll i=0;i<(n);i++) #define REP3(i, a, n) for (ll i=a;i<(n);i++) #define REP4(i, a, b, n) for(ll i=a;i<(n);i+=b) #define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__) #define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name #define RREP1(n) for(ll i=(n)-1;i>=0;i--) #define RREP2(i, n) for(ll i=(n)-1;i>=0;i--) #define RREP3(i, a, n) for(ll i=(n)-1;i>=(a);i--) #define RREP4(i, a, b, n) for(ll i=(n)-1;i>=(a);i-=(b)) #define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__) #define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a)) #define len(n) (long long)(n).size() using ll = long long; using ld = long double; using ull = unsigned long long; using vi = vector; using vvi = vector; using vvvi = vector; using vll = vector; using vvll = vector; using vvvll = vector; using vs = vector; using vvs = vector; using vvvs = vector; using vld = vector; using vvld = vector; using vvvld = vector; using vc = vector; using vvc = vector; using vvvc = vector; using pll = pair; using vpll = vector; using vvpll = vector; ll intpow(ll a,ll b){ ll ans = 1; while (b){ if (b & 1){ ans *= a; } a *= a; b /= 2; } return ans; } ll modpow(ll a,ll b,ll c){ ll ans = 1; while (b){ if (b & 1){ ans *= a; ans %= c; } a *= a; a %= c; b /= 2; } return ans; } template inline T floor(T a, T b) { T q = a / b; T r = a % b; if (r != 0 && ((r < 0) != (b < 0))) q--; return q; } template inline T ceil(T a, T b) { T q = a / b; T r = a % b; if (r != 0 && ((r < 0) == (b < 0))) q++; return q; } template inline T bmod(T a, T b) { T r = a % b; if (r < 0) r += std::abs(b); return r; } template vector>> group_by_first(vector> vec) { sort(vec.begin(), vec.end(), [](auto& a, auto& b) { if (a.first != b.first) return a.first < b.first; return a.second < b.second; }); vector>> res; for (auto& p : vec) { if (res.empty() || res.back().back().first != p.first) { res.push_back({}); } res.back().push_back(p); } return res; } template void input(T&... a){ (cin >> ... >> a); } #define INT(...) int __VA_ARGS__; input(__VA_ARGS__) #define LL(...) ll __VA_ARGS__; input(__VA_ARGS__) #define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__) #define LD(...) ld __VA_ARGS__; input(__VA_ARGS__) #define STR(...) string __VA_ARGS__; input(__VA_ARGS__) #define CHA(...) char __VA_ARGS__; input(__VA_ARGS__) #define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];} #define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];} #define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];} #define VI(name,length) vi name(length);rep(i,length){cin >> name[i];} #define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];} #define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];} #define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];} #define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];} #define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];} #define VC(name,length) vc name(length);rep(i,length){cin >> name[i];} #define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];} #define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];} #define VS(name,length) vs name(length);rep(i,length){cin >> name[i];} #define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];} #define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];} #define PLL(name) pll name;cin>>name.first>>name.second; #define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;} void print(){cout << "\n";} template std::ostream& operator<<(std::ostream& os, const std::pair& p) { os << "(" << p.first << ", " << p.second << ")"; return os; } template std::ostream& operator<<(std::ostream& os, const std::vector& vec) { os << "["; for (size_t i = 0; i < vec.size(); ++i) { os << vec[i]; if (i + 1 < vec.size()) os << ", "; } os << "]"; return os; } template std::ostream& operator<<(std::ostream& os, const std::vector>& a) { os << "["; for (size_t j = 0; j < a.size(); ++j) { os << "(" << a[j].first << ", " << a[j].second << ")"; if (j + 1 < a.size()) os << ", "; } os << "]"; return os; } template std::ostream& operator<<(std::ostream& os, const std::vector>>& mat) { os << "["; for (size_t i = 0; i < mat.size(); ++i) { os << "["; for (size_t j = 0; j < mat[i].size(); ++j) { os << "(" << mat[i][j].first << ", " << mat[i][j].second << ")"; if (j + 1 < mat[i].size()) os << ", "; } os << "]"; if (i + 1 < mat.size()) os << ", "; } os << "]"; return os; } template std::ostream& operator<<(std::ostream& os, const std::set& s) { os << "{"; bool first = true; for (const auto& x : s) { if (!first) os << ", "; os << x; first = false; } os << "}"; return os; } template std::ostream& operator<<(std::ostream& os, const std::map& m) { os << "{"; bool first = true; for (const auto& [key, val] : m) { if (!first) os << ", "; os << key << ": " << val; first = false; } os << "}"; return os; } template void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';} #ifdef LOCAL void debug() { std::cerr << "\n"; } template void debug(const T& a, const Ts&... b) { std::cerr << a; (std::cerr << ... << (std::cerr << ' ', b)); std::cerr << '\n'; } #else #define debug(...) (void)0 #endif void write(){cout << "\n";} template void write(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';} void write(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}} void write(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}} void write(vi x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}} void write(vvi x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}} void write(vvvi x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}} void write(vld x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}} void write(vvld x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}} void write(vvvld x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}} void write(vc x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}} void write(vvc x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}} void write(vvvc x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}} void write(vs x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}} void write(vvs x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}} void write(vvvs x){rep(i,len(x))rep(j,len(x[i]))rep(k,len(x[i][j])){cout << x[i][j][k];if(k!=len(x[i][j])-1){cout << " ";}else if(j!=len(x[i])-1){cout << " | ";}else{cout << '\n';}}} void write(pll x){cout << x.first << ' ' << x.second << '\n';} void write(vpll x){rep(i,len(x)){cout << x[i].first << ' ' << x[i].second << '\n';}} void write(vvpll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j].first << ' ' << x[i][j].second;if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}} template T sum(const std::vector& v) { return std::accumulate(v.begin(), v.end(), T(0)); } template auto le(const Set &s, const typename Set::value_type &x, const typename Set::value_type &ngval = typename Set::value_type(-1)) { auto it = s.upper_bound(x); if (it == s.begin()) return ngval; return *prev(it); } template auto lt(const Set &s, const typename Set::value_type &x, const typename Set::value_type &ngval = typename Set::value_type(-1)) { auto it = s.lower_bound(x); if (it == s.begin()) return ngval; return *prev(it); } template auto ge(const Set &s, const typename Set::value_type &x, const typename Set::value_type &ngval = typename Set::value_type(-1)) { auto it = s.lower_bound(x); if (it == s.end()) return ngval; return *it; } template auto gt(const Set &s, const typename Set::value_type &x, const typename Set::value_type &ngval = typename Set::value_type(-1)) { auto it = s.upper_bound(x); if (it == s.end()) return ngval; return *it; } template bool chmin(T& a, const T& b){ if(a > b){ a = b; return 1; } return 0; } template bool chmax(T& a, const T& b){ if(a < b){ a = b; return 1; } return 0; } template bool chmin(T& a, const U& b){ if(a > T(b)){ a = b; return 1; } return 0; } template bool chmax(T& a, const U& b){ if(a < T(b)){ a = b; return 1; } return 0; } #line 2 "tree/heavy-light-decomposition.hpp" #line 2 "graph/graph-template.hpp" template struct edge { int src, to; T cost; edge(int _to, T _cost) : src(-1), to(_to), cost(_cost) {} edge(int _src, int _to, T _cost) : src(_src), to(_to), cost(_cost) {} edge &operator=(const int &x) { to = x; return *this; } operator int() const { return to; } }; template using Edges = vector>; template using WeightedGraph = vector>; using UnweightedGraph = vector>; // Input of (Unweighted) Graph UnweightedGraph graph(int N, int M = -1, bool is_directed = false, bool is_1origin = true) { UnweightedGraph g(N); if (M == -1) M = N - 1; for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; if (is_1origin) x--, y--; g[x].push_back(y); if (!is_directed) g[y].push_back(x); } return g; } // Input of Weighted Graph template WeightedGraph wgraph(int N, int M = -1, bool is_directed = false, bool is_1origin = true) { WeightedGraph g(N); if (M == -1) M = N - 1; for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; T c; cin >> c; if (is_1origin) x--, y--; g[x].emplace_back(x, y, c); if (!is_directed) g[y].emplace_back(y, x, c); } return g; } // Input of Edges template Edges esgraph([[maybe_unused]] int N, int M, int is_weighted = true, bool is_1origin = true) { Edges es; for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; T c; if (is_weighted) cin >> c; else c = 1; if (is_1origin) x--, y--; es.emplace_back(x, y, c); } return es; } // Input of Adjacency Matrix template vector> adjgraph(int N, int M, T INF, int is_weighted = true, bool is_directed = false, bool is_1origin = true) { vector> d(N, vector(N, INF)); for (int _ = 0; _ < M; _++) { int x, y; cin >> x >> y; T c; if (is_weighted) cin >> c; else c = 1; if (is_1origin) x--, y--; d[x][y] = c; if (!is_directed) d[y][x] = c; } return d; } /** * @brief グラフテンプレート * @docs docs/graph/graph-template.md */ #line 4 "tree/heavy-light-decomposition.hpp" template struct HeavyLightDecomposition { private: void dfs_sz(int cur) { size[cur] = 1; for (auto& dst : g[cur]) { if (dst == par[cur]) { if (g[cur].size() >= 2 && int(dst) == int(g[cur][0])) swap(g[cur][0], g[cur][1]); else continue; } depth[dst] = depth[cur] + 1; par[dst] = cur; dfs_sz(dst); size[cur] += size[dst]; if (size[dst] > size[g[cur][0]]) { swap(dst, g[cur][0]); } } } void dfs_hld(int cur) { down[cur] = id++; for (auto dst : g[cur]) { if (dst == par[cur]) continue; nxt[dst] = (int(dst) == int(g[cur][0]) ? nxt[cur] : int(dst)); dfs_hld(dst); } up[cur] = id; } // [u, v) vector> ascend(int u, int v) const { vector> res; while (nxt[u] != nxt[v]) { res.emplace_back(down[u], down[nxt[u]]); u = par[nxt[u]]; } if (u != v) res.emplace_back(down[u], down[v] + 1); return res; } // (u, v] vector> descend(int u, int v) const { if (u == v) return {}; if (nxt[u] == nxt[v]) return {{down[u] + 1, down[v]}}; auto res = descend(u, par[nxt[v]]); res.emplace_back(down[nxt[v]], down[v]); return res; } public: G& g; int root, id; vector size, depth, down, up, nxt, par; HeavyLightDecomposition(G& _g, int _root = 0) : g(_g), root(_root), id(0), size(g.size(), 0), depth(g.size(), 0), down(g.size(), -1), up(g.size(), -1), nxt(g.size(), root), par(g.size(), root) { dfs_sz(root); dfs_hld(root); } pair idx(int i) const { return make_pair(down[i], up[i]); } template void path_query(int u, int v, bool vertex, const F& f) { int l = lca(u, v); for (auto&& [a, b] : ascend(u, l)) { int s = a + 1, t = b; s > t ? f(t, s) : f(s, t); } if (vertex) f(down[l], down[l] + 1); for (auto&& [a, b] : descend(l, v)) { int s = a, t = b + 1; s > t ? f(t, s) : f(s, t); } } template void path_noncommutative_query(int u, int v, bool vertex, const F& f) { int l = lca(u, v); for (auto&& [a, b] : ascend(u, l)) f(a + 1, b); if (vertex) f(down[l], down[l] + 1); for (auto&& [a, b] : descend(l, v)) f(a, b + 1); } template void subtree_query(int u, bool vertex, const F& f) { f(down[u] + int(!vertex), up[u]); } int lca(int a, int b) { while (nxt[a] != nxt[b]) { if (down[a] < down[b]) swap(a, b); a = par[nxt[a]]; } return depth[a] < depth[b] ? a : b; } int dist(int a, int b) { return depth[a] + depth[b] - depth[lca(a, b)] * 2; } }; /** * @brief Heavy Light Decomposition(重軽分解) * @docs docs/tree/heavy-light-decomposition.md */ #include ll op(ll x,ll y){ return min(x,y); } ll e2(){ return 1LL<<60; } int main(){ ios::sync_with_stdio(false); std::cin.tie(nullptr); LL(n,m); vvll edge(n); vpll e; rep(i,n-1){ LL(u,v); u--; v--; edge[u].push_back(v); edge[v].push_back(u); e.emplace_back(u,v); } vll dist(n,1LL<<60); auto dfs = [&](auto dfs,ll now,ll p) -> void { for(ll to:edge[now]){ if(to == p){continue;} dist[to] = dist[now] + 1; dfs(dfs,to,now); } }; dist[0] = 0; dfs(dfs,0,-1); HeavyLightDecomposition hld(edge); atcoder::segtree st(n); rep(i,n-1){ auto [u,v] = e[i]; if(dist[u] > dist[v]){ swap(u,v); } st.set(hld.idx(v).first,i); } ll ans = 0; auto que = [&](int u, int v){ chmin(ans,st.prod(u,v)); }; vll a(n+1,0); rep(i,m){ LL(u,v); u--; v--; ans = 1LL<<60; hld.path_query(u,v,false,que); a[0]++; a[ans]--; } rep(i,n){ a[i+1] += a[i]; } rep(i,n-1){ print(a[i]); } }