#include <bits/stdc++.h>
using namespace std;
const int MAXN = 200111;
const int N = 20;
vector<int> adj[MAXN];
// up[i][j] is the 2^j-th ancestor of node i, level[i] is
// the depth of node i
int up[MAXN][N], level[MAXN];
// Depth-First Search (DFS) to calculate the depth of each
// node and initialize the first ancestor
void dfs(int node, int parent, int lv)
{
// Set the level (depth) of the current node
level[node] = lv;
// Set the first ancestor of the current node
up[node][0] = parent;
for (auto child : adj[node]) {
if (child != parent) {
// If the child is not the parent, continue the
// DFS
dfs(child, node, lv + 1);
}
}
}
// Preprocess to calculate the 2^j-th ancestor for each node
// using binary lifting
void prep(int n)
{
// Start DFS from node 1 (assuming 1-based index)
dfs(1, -1, 0);
for (int j = 1; j < N; j++) {
for (int i = 1; i <= n; i++) {
// If the (j-1)-th ancestor exists
if (up[i][j - 1] != -1) {
// Set the j-th ancestor using (j-1)-th
// ancestors
up[i][j] = up[up[i][j - 1]][j - 1];
}
else {
up[i][j] = -1;
}
}
}
}
// Function to find the Lowest Common Ancestor (LCA) of
// nodes a and b
int LCA(int a, int b){
// Ensure b is the deeper node
if (level[b] < level[a])
swap(a, b);
int d = level[b] - level[a];
// Bring b to the same level as a
while (d) {
int i = log2(d);
b = up[b][i];
d -= (1 << i);
}
if (a == b)
return a;
// Binary lifting to find the LCA
for (int i = N - 1; i >= 0; i--) {
if (up[a][i] != -1 && up[a][i] != up[b][i]) {
a = up[a][i];
b = up[b][i];
}
}
// Return the parent of a (or b) which is the LCA
return up[a][0];
}
vector<int> distance(vector<pair<int, int> >& edges,
vector<pair<int, int> >& queries,
int n, int q)
{
vector<int> dist;
for (int i = 0; i < n - 1; i++) {
int a = edges[i].first, b = edges[i].second;
// Add edge a-b
adj[a].push_back(b);
// Add edge b-a (since the tree is undirected)
adj[b].push_back(a);
}
// Root's parent is set to -
up[1][0] = -1;
// Root's level is set to 0
level[1] = 0;
// Preprocess the tree for LCA queries
prep(n);
for (int i = 0; i < q; i++) {
int a = queries[i].first, b = queries[i].second;
// Calculate the distance between a and b
dist.push_back(level[a] + level[b]
- 2 * level[LCA(a, b)]);
}
return dist;
}
int main()
{
int n = 5, q = 3;
vector<pair<int, int> > edges
= { { 1, 2 }, { 1, 3 }, { 3, 4 }, { 3, 5 } };
vector<pair<int, int> > queries
= { { 1, 3 }, { 2, 5 } };
vector<int> dist = distance(edges, queries, n, q);
for (int i = 0; i < q; i++)
cout << dist[i] << " ";
return 0;
}