import java.io.*;
import java.util.*;
public class Main {
static int N, Q, LOG;
static List<Integer>[] g;
static int[][] up; // up[k][v] = v의 2^k번째 조상 (없으면 0)
static int[] depth;
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
Q = Integer.parseInt(st.nextToken());
g = new ArrayList[N + 1];
for (int i = 1; i <= N; i++) g[i] = new ArrayList<>();
for (int i = 0; i < N - 1; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
g[a].add(b); g[b].add(a);
}
LOG = 1;
while ((1 << LOG) <= N) LOG++;
up = new int[LOG][N + 1];
depth = new int[N + 1];
// 전처리: root = 1
dfs(1, 0);
for (int k = 1; k < LOG; k++) {
for (int v = 1; v <= N; v++) {
int mid = up[k - 1][v];
up[k][v] = (mid == 0) ? 0 : up[k - 1][mid];
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Q; i++) {
st = new StringTokenizer(br.readLine());
int u = Integer.parseInt(st.nextToken());
int v = Integer.parseInt(st.nextToken());
sb.append(lca(u, v)).append('\n');
}
System.out.print(sb);
}
// 부모 p에서 자식 v로 내려가며 depth와 up[0] 채움 (재귀 DFS)
static void dfs(int v, int p) {
up[0][v] = p;
depth[v] = (p == 0) ? 0 : depth[p] + 1;
for (int to : g[v]) if (to != p) dfs(to, v);
}
// LCA(u, v)
static int lca(int u, int v) {
if (depth[u] < depth[v]) { int t = u; u = v; v = t; }
// 1) 깊이 맞추기
int diff = depth[u] - depth[v];
for (int k = 0; k < LOG; k++) if (((diff >> k) & 1) == 1) u = up[k][u];
if (u == v) return u;
// 2) 동시에 점프 (바로 위가 다를 때까지)
for (int k = LOG - 1; k >= 0; k--) {
if (up[k][u] != up[k][v]) {
u = up[k][u];
v = up[k][v];
}
}
// 3) 부모가 LCA
return up[0][u];
}
}