#include <bits/stdc++.h>   const int MAXN = 2e5 + 7;   struct Edge {     int t, next;   } edge[MAXN << 1];   int head[MAXN], cnt;   int size[MAXN];   int dfn[MAXN], pos[MAXN], ts = 0;   int n, m;   int dist[MAXN], deep[MAXN];   int f[MAXN][19];   int t1 = 1, t2 = 1;   struct SegmentTree;   struct Questions;   SegmentTree *newNode(int, int, SegmentTree *, SegmentTree *);   struct SegmentTree {     int l, r, mid;     SegmentTree *lc, *rc;     int val, add, max;     static SegmentTree *build(int l, int r) {       SegmentTree *ret = NULL;       if (l == r) {         ret = newNode(l, r, NULL, NULL);         ret->val = ret->max = dist[pos[l]];         return ret;       } else {         int mid = l + (r - l) / 2;         ret = newNode(l, r, build(l, mid), build(mid + 1, r));         ret->pushUp();         return ret;       }     }     void pushUp() { max = std::max(lc->max, rc->max); }     void pushDown() {       if (add) {         lc->plus(add), rc->plus(add);         add = 0;       }     }     void plus(int a) {       if (l == r) val += a;       add += a;       max += a;     }     void solveAdd(int left, int right, int delta) {       if (l == left && r == right) return plus(delta);       pushDown();       if (right <= mid)         lc->solveAdd(left, right, delta);       else if (left > mid)         rc->solveAdd(left, right, delta);       else         lc->solveAdd(left, mid, delta), rc->solveAdd(mid + 1, right, delta);       pushUp();     }     int queryMax(int left, int right) {       if (l == left && r == right) return max;       pushDown();       if (right <= mid)         return lc->queryMax(left, right);       else if (left > mid)         return rc->queryMax(left, right);       else         return std::max(lc->queryMax(left, mid), rc->queryMax(mid + 1, right));     }   } * root, pool[MAXN], *tail = pool;   SegmentTree *newNode(int l, int r, SegmentTree *lc, SegmentTree *rc) {     SegmentTree *ret = ++tail;     ret->l = l, ret->r = r, ret->mid = l + (r - l) / 2;     ret->lc = lc, ret->rc = rc;     ret->val = 0, ret->add = 0, ret->max = INT_MIN;     return ret;   }   struct Questions {     int u, v, mid;   } q[MAXN];   struct Ans {     int r, node, pos, ans;   } a1[MAXN], a2[MAXN];   std::vector<Ans> v1[MAXN], v2[MAXN];   void add(int u, int v) {     cnt++;     edge[cnt].t = v;     edge[cnt].next = head[u];     head[u] = cnt;   }   void dfs1(int u, int pre) {     f[u][0] = pre;     dfn[u] = ++ts;     size[u] = 1;     pos[ts] = u;     for (int e = head[u]; e; e = edge[e].next) {       int v = edge[e].t;       if (v == pre) continue;       dist[v] = dist[u] + 1;       deep[v] = deep[u] + 1;       dfs1(v, u);       size[u] += size[v];     }   }   int getLca(int x, int y) {     if (deep[x] > deep[y]) std::swap(x, y);     for (int i = 18; i >= 0; i--) {       if (deep[f[y][i]] >= deep[x]) y = f[y][i];     }     if (x == y) return x;     for (int i = 18; i >= 0; i--) {       if (f[x][i] != f[y][i]) {         x = f[x][i];         y = f[y][i];       }     }     return f[x][0];   }   int getMid(int u, int len) {     int e = 0;     while (len) {       if (len & 1) u = f[u][e];       len >>= 1;       e++;     }     return u;   }   void dfs2(int u, int pre) {     while (a1[t1].r == u && t1 <= m) {       a1[t1].ans = root->queryMax(dfn[a1[t1].node],                                   dfn[a1[t1].node] + size[a1[t1].node] - 1);       t1++;     }     while (a2[t2].r == u && t2 <= m) {       if (dfn[a2[t2].node] > 1)         a2[t2].ans =             std::max(a2[t2].ans, root->queryMax(1, dfn[a2[t2].node] - 1));       if (dfn[a2[t2].node] + size[a2[t2].node] - 1 < n)         a2[t2].ans = std::max(             a2[t2].ans, root->queryMax(dfn[a2[t2].node] + size[a2[t2].node], n));       t2++;     }     for (int e = head[u]; e; e = edge[e].next) {       int v = edge[e].t;       if (v == pre) continue;       root->solveAdd(dfn[v], dfn[v] + size[v] - 1, -1);       if (dfn[v] > 1) root->solveAdd(1, dfn[v] - 1, 1);       if (dfn[v] + size[v] - 1 < n) root->solveAdd(dfn[v] + size[v], n, 1);       dfs2(v, u);       root->solveAdd(dfn[v], dfn[v] + size[v] - 1, 1);       if (dfn[v] > 1) root->solveAdd(1, dfn[v] - 1, -1);       if (dfn[v] + size[v] - 1 < n) root->solveAdd(dfn[v] + size[v], n, -1);     }   }   bool cmp1(Ans x, Ans y) {     if (dfn[x.r] == dfn[y.r]) return dfn[x.node] < dfn[y.node];     return dfn[x.r] < dfn[y.r];   }   bool cmp2(Ans x, Ans y) { return x.pos < y.pos; }   int main(int argc, char *argv[]) {     scanf( %d , &n);     int u, v;     for (int i = 1; i <= n - 1; i++) {       scanf( %d %d , &u, &v);       add(u, v);       add(v, u);     }     deep[1] = 1;     dfs1(1, 0);     root = SegmentTree::build(1, n);     for (int j = 1; j <= 18; j++) {       for (int i = 1; i <= n; i++) {         f[i][j] = f[f[i][j - 1]][j - 1];       }     }     int lca, len, mid;     scanf( %d , &m);     for (int i = 1; i <= m; i++) {       scanf( %d %d , &u, &v);       lca = getLca(u, v);       len = dist[u] + dist[v] - 2 * dist[lca];       if (deep[u] < deep[v]) std::swap(u, v);       mid = getMid(u, (len - 1) / 2);       q[i] = Questions{u, v, mid};       a1[i] = Ans{u, mid, i, INT_MIN};       a2[i] = Ans{v, mid, i, INT_MIN};     }     std::sort(a1 + 1, a1 + m + 1, cmp1);     std::sort(a2 + 1, a2 + m + 1, cmp1);     dfs2(1, 0);     std::sort(a1 + 1, a1 + m + 1, cmp2);     std::sort(a2 + 1, a2 + m + 1, cmp2);     for (int i = 1; i <= m; i++) {       printf( %d n , std::max(a1[i].ans, a2[i].ans));     }     return 0;   }