class UnionFind: def __init__(self): self.Nodes = 0 self.par = [] self.siz = [] # 頂点数の設定 def init(self, N: int): assert 0 <= N for _ in range(self.Nodes, N): self.par.append(-1) self.siz.append(1) self.Nodes = N # リーダーの取得 def leader(self, x: int) -> int: assert 0 <= x < self.Nodes if self.par[x] == -1: return x self.par[x] = self.leader(self.par[x]) return self.par[x] # aとbが同じ連結成分か判定 def same(self, a: int, b: int) -> bool: assert 0 <= a < self.Nodes assert 0 <= b < self.Nodes return self.leader(a) == self.leader(b) # aとbをつなぐ def merge(self, a: int, b: int) -> bool: assert 0 <= a < self.Nodes assert 0 <= b < self.Nodes pa = self.leader(a) pb = self.leader(b) res = (pa == pb) if not res: if self.siz[pa] < self.siz[pb]: self.par[pa] = pb self.siz[pb] += self.siz[pa] else: self.par[pb] = pa self.siz[pa] += self.siz[pb] return res # 同じ連結成分のサイズ def size(self, a: int) -> int: assert 0 <= a < self.Nodes return self.siz[self.leader(a)] # 同じ連結成分内の頂点(O(N)) def same_node(self, a: int): assert 0 <= a < self.Nodes return [i for i in range(self.Nodes) if self.same(a, i)] # 連結成分ごとのグループを返す def groups(self): res = [[] for _ in range(self.Nodes)] for i in range(self.Nodes): res[self.leader(i)].append(i) return [g for g in res if g] # ---- main ---- def main(): import sys input = sys.stdin.readline N, M = map(int, input().split()) edges = [tuple(map(int, input().split())) for _ in range(N - 1)] edges = [(u - 1, v - 1) for u, v in edges] d = UnionFind() d.init(N) # 各段階のUnionFindを保持 E = [None] * (N - 1) for i in reversed(range(N - 1)): d.merge(edges[i][0], edges[i][1]) # Pythonでは参照コピーなので、ディープコピーを作る uf_copy = UnionFind() uf_copy.Nodes = d.Nodes uf_copy.par = d.par.copy() uf_copy.siz = d.siz.copy() E[i] = uf_copy ans = [0] * (N - 1) ans[0] = M for _ in range(M): s, t = map(int, input().split()) s -= 1 t -= 1 ok = 0 ng = N - 1 while abs(ok - ng) > 1: mid = (ok + ng) // 2 if E[mid].same(s, t): ok = mid else: ng = mid ans[ok] -= 1 for i in range(1, N - 1): ans[i] += ans[i - 1] for a in ans: print(a) if __name__ == "__main__": main()