#include using namespace std; struct Edge { long long to; }; using Graph = vector>; struct LCA { vector> parent; // parent[k][u]:= u の 2^k 先の親 vector dist; // root からの距離 LCA(const Graph &G, int root = 0) { init(G, root); } // 初期化 void init(const Graph &G, int root = 0) { int V = G.size(); int K = 1; while ((1 << K) < V) K++; parent.assign(K, vector(V, -1)); dist.assign(V, -1); dfs(G, root, -1, 0); for (int k = 0; k + 1 < K; k++) { for (int v = 0; v < V; v++) { if (parent[k][v] < 0) { parent[k + 1][v] = -1; } else { parent[k + 1][v] = parent[k][parent[k][v]]; } } } } // 根からの距離と1つ先の頂点を求める void dfs(const Graph &G, int v, int p, int d) { parent[0][v] = p; dist[v] = d; for (auto e : G[v]) { if (e.to != p) dfs(G, e.to, v, d + 1); } } int query(int u, int v) { if (dist[u] < dist[v]) swap(u, v); // u の方が深いとする int K = parent.size(); // LCA までの距離を同じにする for (int k = 0; k < K; k++) { if ((dist[u] - dist[v]) >> k & 1) { u = parent[k][u]; } } // 二分探索で LCA を求める if (u == v) return u; for (int k = K - 1; k >= 0; k--) { if (parent[k][u] != parent[k][v]) { u = parent[k][u]; v = parent[k][v]; } } return parent[0][u]; } }; int main() { int N, Q; cin >> N >> Q; Graph G(N); for (int i = 0; i < N - 1; i++){ int A, B; cin >> A >> B; A--; B--; G[A].push_back(Edge{B}); G[B].push_back(Edge{A}); } LCA lca(G); vector d(N, 1); auto f = [&](auto f, int v, int c = -1) -> int { for (auto e : G[v]){ if (e.to == c){ continue; } d[v] += f(f, e.to, v); } return d[v]; }; f(f, 0); while (Q--){ int S, T; cin >> S >> T; S--; T--; int i = lca.query(S, T); int ans = N - d[i]; if (lca.dist[S] % 2 == lca.dist[T] % 2){ ans++; } cout << ans << '\n'; } }