#include <bits/stdc++.h>
using namespace std;
const long long mod = 1000000007;
const double pi = 3.14159265358979323846;
struct segmentTree {
  inline int left(int n) { return (n << 1); }
  inline int right(int n) { return ((n << 1) + 1); }
  vector<int> st, lazy, A;
  int size;
  segmentTree(vector<int> &arr) {
    A = arr;
    size = A.size();
    lazy.resize(4 * size, 0LL);
    st.resize(4 * size);
    build(1, 0, size - 1);
  }
  void build(int node, int a, int b) {
    if (a > b) return;
    if (a == b) {
      st[node] = A[a];
      return;
    }
    build(left(node), a, (a + b) / 2);
    build(right(node), (a + b) / 2 + 1, b);
    st[node] = max(st[left(node)], st[right(node)]);
  }
  void update(int i, int j, int value) { update(i, j, value, 1, 0, size - 1); }
  void update(int i, int j, int value, int node, int a, int b) {
    if (lazy[node] != 0LL) {
      st[node] += lazy[node];
      if (a != b) {
        lazy[left(node)] += lazy[node];
        lazy[right(node)] += lazy[node];
      }
      lazy[node] = 0LL;
    }
    if (a > b || a > j || b < i) return;
    if (a >= i && b <= j) {
      st[node] += value;
      if (a != b) {
        lazy[left(node)] += value;
        lazy[right(node)] += value;
      }
      return;
    }
    update(i, j, value, left(node), a, (a + b) / 2);
    update(i, j, value, right(node), (a + b) / 2 + 1, b);
    st[node] = max(st[left(node)], st[right(node)]);
  }
  long long query(int i, int j) { return query(i, j, 1, 0, size - 1); }
  long long query(int i, int j, int node, int a, int b) {
    if (a > b || a > j || b < i) return -100000;
    if (lazy[node] != 0LL) {
      st[node] += lazy[node];
      if (a != b) {
        lazy[left(node)] += lazy[node];
        lazy[right(node)] += lazy[node];
      }
      lazy[node] = 0LL;
    }
    if (a >= i && b <= j)
      return st[node];
    else
      return max(query(i, j, left(node), a, (a + b) / 2),
                 query(i, j, right(node), (a + b) / 2 + 1, b));
  }
};
vector<vector<int> > grafo, SP;
vector<int> DD, RMG, PD, LOG;
vector<bool> visitado;
vector<int> diametro;
int ANiv(int i, int N) {
  while (DD[i] != N) {
    i = SP[i][LOG[DD[i] - N]];
  }
  return i;
}
int LCA(int i, int j) {
  int k = 0;
  if (DD[i] != DD[j]) {
    if (DD[i] > DD[j]) {
      i = ANiv(i, DD[j]);
    } else {
      j = ANiv(j, DD[i]);
    }
  }
  while (i != j) {
    k = LOG[DD[i]];
    while (SP[i][k] == SP[j][k] && k > 0) {
      k--;
    }
    i = SP[i][k];
    j = SP[j][k];
  }
  return i;
}
int main() {
  int n, a, b, Ber1 = 0, Ber2, Dia = 0, LogMax, k = 0;
  queue<int> q;
  stack<int> q2;
  cin >> n;
  DD.resize(n, 0);
  grafo.resize(n);
  RMG.resize(n, 0);
  PD.resize(n, 0);
  vector<int> parent(n), MaxB1, MaxB2;
  visitado.resize(n, false);
  LOG.resize(n + 4, 0);
  a = 1;
  k = 0;
  for (int i = 0; i < n + 4; i++) {
    if (i == a) {
      k++;
      a *= 2;
    }
    LOG[i] = k - 1;
  }
  LogMax = LOG[n];
  SP.resize(n, vector<int>(LogMax));
  for (int i = 0; i < n - 1; i++) {
    cin >> a >> b;
    grafo[a - 1].push_back(b - 1);
    grafo[b - 1].push_back(a - 1);
  }
  DD[0] = 0;
  q.push(0);
  visitado[0] = true;
  while (!q.empty()) {
    a = q.front();
    q.pop();
    for (int i = 0; i < grafo[a].size(); i++) {
      int is = grafo[a][i];
      if (!visitado[is]) {
        visitado[is] = true;
        DD[is] = DD[a] + 1;
        if (DD[is] > Dia) {
          Dia = DD[is];
          Ber1 = is;
        }
        q.push(is);
      }
    }
  }
  DD[Ber1] = 0;
  parent[Ber1] = -1;
  q.push(Ber1);
  Dia = 0;
  visitado[Ber1] = false;
  while (!q.empty()) {
    a = q.front();
    q.pop();
    for (int i = 0; i < grafo[a].size(); i++) {
      int is = grafo[a][i];
      if (visitado[is]) {
        parent[is] = a;
        visitado[is] = false;
        q.push(is);
        DD[is] = DD[a] + 1;
        if (DD[is] > Dia) {
          Dia = DD[is];
          Ber2 = is;
        }
      }
    }
  }
  a = Ber2;
  b = 0;
  while (a != -1) {
    diametro.push_back(a);
    DD[a] = 0;
    PD[a] = b;
    b++;
    visitado[a] = true;
    a = parent[a];
    if (a != -1) {
      q.push(a);
    }
  }
  while (!q.empty()) {
    a = q.front();
    q.pop();
    for (int i = 0; i < grafo[a].size(); i++) {
      int is = grafo[a][i];
      if (!visitado[is]) {
        visitado[is] = true;
        DD[is] = DD[a] + 1;
        SP[is][0] = a;
        for (int j = 1; j <= LOG[DD[is]]; j++) {
          SP[is][j] = SP[SP[is][j - 1]][j - 1];
        }
        PD[is] = PD[a];
        q.push(is);
      }
    }
    if (grafo[a].size() == 1) {
      q2.push(a);
      RMG[a] = 0;
      visitado[a] = true;
    }
  }
  while (!q2.empty()) {
    a = q2.top();
    q2.pop();
    for (int i = 0; i < grafo[a].size(); i++) {
      int is = grafo[a][i];
      if (DD[is] >= DD[a]) {
        continue;
      } else {
        if (RMG[is] < RMG[a] + 1) {
          RMG[is] = RMG[a] + 1;
        }
        q2.push(is);
      }
    }
  }
  MaxB2.resize(diametro.size(), 0);
  MaxB1.resize(diametro.size(), 0);
  for (int i = 0; i < diametro.size(); i++) {
    int is = diametro[i];
    MaxB1[i] = PD[is] + RMG[is];
    MaxB2[i] = Dia - PD[is] + RMG[is];
  }
  segmentTree ST1(MaxB1);
  segmentTree ST2(MaxB2);
  int quer, Max, Dis, Mpos, DD1, DD2, PtoMedio, lca, VST1, VST2, NMi, NMa,
      delta, path, desde, hasta;
  cin >> quer;
  for (int i = 0; i < quer; i++) {
    cin >> a >> b;
    a--;
    b--;
    if (PD[a] == PD[b]) {
      lca = LCA(a, b);
      if (lca == a || lca == b) {
        Max = min(RMG[a], RMG[b]);
      } else {
        Max = max(RMG[a], RMG[b]);
      }
      Dis = min(DD[a], DD[b]);
      Mpos = max(PD[a], Dia - PD[a]);
      if (Dis + Mpos > Max) {
        Max = Dis + Mpos;
      }
    } else {
      Max = max(RMG[a], RMG[b]);
      delta = (DD[a] > DD[b] ? DD[a] - DD[b] : DD[b] - DD[a]);
      Dis = (PD[a] > PD[b] ? PD[a] - PD[b] : PD[b] - PD[a]);
      if (PD[a] > PD[b]) {
        swap(a, b);
      }
      Max = max(Max, min(PD[a] + DD[a], PD[b] + DD[b]));
      Max = max(Max, min(Dia - PD[b] + DD[b], Dia - PD[a] + DD[a]));
      if (PD[b] - PD[a] > 1) {
        if (delta >= Dis) {
          if (DD[a] < DD[b]) {
            VST1 = ST1.query(PD[a] + 1, PD[b] - 1) - PD[a] + DD[a];
            Max = max(Max, VST1);
          } else {
            VST2 = ST2.query(PD[a] + 1, PD[b] - 1) - Dia + PD[b] + DD[b];
            Max = max(Max, VST2);
          }
        } else {
          path = DD[a] + DD[b] + PD[b] - PD[a];
          delta = (DD[a] > DD[b] ? -delta : delta);
          PtoMedio = (PD[a] + PD[b] + delta) / 2;
          int arista = (path) % 2;
          if (path % 2 == 0) {
            VST1 = ST1.query(PD[a] + 1, PtoMedio) - PD[a] + DD[a];
            VST2 = ST2.query(PtoMedio, PD[b] - 1) - Dia + PD[b] + DD[b];
          } else {
            VST1 = ST1.query(PD[a] + 1, PtoMedio) - PD[a] + DD[a];
            VST2 = ST2.query(PtoMedio + 1, PD[b] - 1) - Dia + PD[b] + DD[b];
          }
          Max = max(Max, VST2);
          Max = max(Max, VST1);
        }
      }
    }
    cout << Max;
    cout << endl;
  }
}
