1.树上倍增
#include <queue>
#include <cstdio>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXTEP = 45;
int n, m;
int depth[MAXN], f[MAXN][MAXTEP];
int len, head[MAXN];
struct edge {
int to, next;
}e[MAXN * 2];
void add (int, int);
void build ();
int lca (int, int);
int main () {
scanf ("%d %d", &n, &m);
for (int i = 1; i < n; i++) {
int x, y; scanf ("%d %d", &x, &y);
add (x, y); add (y, x);
}
build ();
for (int i = 1; i <= m; i++) {
int x, y; scanf ("%d %d", &x, &y);
printf ("%d\n", lca (x, y));
}
return 0;
}
void add (int x, int y) {
e[++len].to = y;
e[len].next = head[x];
head[x] = len;
}
void build () {
queue <int> q; q.push (1); depth[1] = 1;
while (!q.empty