#include <bits/stdc++.h>
using namespace std;
void _print() { cout << '\n'; }
void print() { cout << '\n'; }
template <typename T, typename... Ts>
void _print(const T& value, const Ts&... values) {
  cout << ' ' << value;
  _print(values...);
}
template <typename T, typename... Ts>
void print(const T& value, const Ts&... values) {
  cout << value;
  _print(values...);
}
const int N = 1e5 + 5;
using ll = long long;
struct Query {
  int id;
  pair<int, int> seg1, seg2;
  Query(int _1, pair<int, int> _2, pair<int, int> _3)
      : id(_1), seg1(_2), seg2(_3){};
};
int par[18][N], depth[N], sta[N], en[N], child[N];
int ansQuery[N];
bool done[N];
vector<int> a[N];
int n, Time = 0;
vector<Query> query[N];
const int INF = 1e9;
class ITrangeMaxMin {
 private:
  int n, f[4 * N];
  void init(int k, int l, int r) {
    f[k] = -INF;
    if (l == r) return;
    init(k * 2, l, ((l + r) / 2));
    init(k * 2 + 1, ((l + r) / 2) + 1, r);
  }
  void update(int k, int l, int r, int pos, int val) {
    if (r < pos || pos < l || l > r) return;
    if (pos <= l && r <= pos) {
      f[k] = val;
      return;
    }
    update(k * 2, l, ((l + r) / 2), pos, val);
    update(k * 2 + 1, ((l + r) / 2) + 1, r, pos, val);
    f[k] = max(f[k * 2], f[k * 2 + 1]);
  }
  int get(int k, int l, int r, int L, int R) {
    if (r < L || R < l || l > r) return -INF;
    if (L <= l && r <= R) return f[k];
    return max(get(k * 2, l, ((l + r) / 2), L, R),
               get(k * 2 + 1, ((l + r) / 2) + 1, r, L, R));
  }

 public:
  void init(int _n) {
    n = _n;
    init(1, 0, n + 1);
  }
  int get(int l, int r) { return get(1, 0, n + 1, l, r); };
  void update(int pos, int val) { update(1, 0, n + 1, pos, val); };
} IT;
void pdfs(int u, int p) {
  par[0][u] = p;
  sta[u] = ++Time;
  for (auto v : a[u]) {
    if (v != p) {
      depth[v] = depth[u] + 1;
      pdfs(v, u);
    }
  }
  en[u] = Time;
}
void dfsCen(int u, int p) {
  child[u] = 1;
  for (auto v : a[u]) {
    if (v != p && !done[v]) {
      dfsCen(v, u);
      child[u] += child[v];
    }
  }
}
struct custom_hash {
  static unsigned long long splitmix64(unsigned long long x) {
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }
  size_t operator()(pair<int, int> x) const {
    static const unsigned long long FIXED_RANDOM1 =
        chrono::steady_clock::now().time_since_epoch().count();
    static const unsigned long long FIXED_RANDOM2 =
        chrono::steady_clock::now().time_since_epoch().count();
    return hash<unsigned long long>()(splitmix64(x.first + FIXED_RANDOM1) ^
                                      splitmix64(x.second + FIXED_RANDOM2));
  }
};
using hashmap = unordered_map<pair<int, int>, int, custom_hash>;
hashmap cache;
int lca(int p, int q) {
  if (depth[p] < depth[q]) swap(p, q);
  if (cache.find({p, q}) != cache.end()) return cache[{p, q}];
  for (int i = (17); i >= (0); i--) {
    if (depth[par[i][p]] >= depth[q]) p = par[i][p];
  }
  if (p == q) return cache[{p, q}] = p;
  for (int i = (17); i >= (0); i--) {
    if (par[i][p] != par[i][q]) p = par[i][p], q = par[i][q];
  }
  return cache[{p, q}] = par[0][p];
}
int jump(int p, int d) {
  for (int i = (0); i <= (17); i++)
    if (((d >> i) & 1)) p = par[i][p];
  return p;
}
int jumpTow(int u, int d, int v) {
  int p = lca(u, v);
  int dx = depth[u] - depth[p] + depth[v] - depth[p];
  if (d < depth[u] - depth[p])
    return jump(u, d);
  else
    return jump(v, dx - d);
}
void makelca() {
  pdfs(1, 1);
  for (int i = (1); i <= (17); i++) {
    for (int j = (1); j <= (n); j++) {
      par[i][j] = par[i - 1][par[i - 1][j]];
    }
  }
}
void prepQuery(int u, int v, int id) {
  if (depth[u] < depth[v]) swap(u, v);
  int p = lca(u, v);
  int d = depth[u] - depth[p] + depth[v] - depth[p];
  auto sep = jumpTow(u, d / 2, v);
  if (v != p && sep == p) sep = jumpTow(u, d / 2 - 1, v);
  query[u].push_back({id, {sta[sep], en[sep]}, {sta[sep], en[sep]}});
  query[v].push_back({id, {1, sta[sep] - 1}, {en[sep] + 1, n}});
}
int findCen(int u) {
  dfsCen(u, u);
  int sz = child[u];
  while (true) {
  up:
    for (auto v : a[u]) {
      if (child[v] < child[u] && child[v] * 2 > sz) {
        u = v;
        goto up;
      }
    }
    return u;
  }
}
void dfsMod(int u, int p, int d, int type) {
  for (auto v : a[u]) {
    if (v == p || done[v]) continue;
    dfsMod(v, u, d + 1, type);
  }
  if (type == 1)
    IT.update(sta[u], d);
  else
    IT.update(sta[u], -INF);
}
void handleQuery(int u, int d) {
  if (query[u].empty()) return;
  for (auto cur : query[u]) {
    auto& ret = ansQuery[cur.id];
    ret = max(ret, IT.get(cur.seg1.first, cur.seg1.second) + d);
    ret = max(ret, IT.get(cur.seg2.first, cur.seg2.second) + d);
  }
}
void dfsSolve(int u, int p, int d) {
  for (auto v : a[u]) {
    if (v == p || done[v]) continue;
    dfsSolve(v, u, d + 1);
  }
  handleQuery(u, d);
}
void solve(int u) {
  u = findCen(u);
  dfsMod(u, u, 0, 1);
  handleQuery(u, 0);
  for (auto v : a[u]) {
    if (done[v]) continue;
    dfsMod(v, u, 1, -1);
    dfsSolve(v, u, 1);
    dfsMod(v, u, 1, 1);
  }
  dfsMod(u, u, u, -1);
  done[u] = true;
  for (auto v : a[u]) {
    if (!done[v]) solve(v);
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  for (int i = (1); i <= (n - 1); i++) {
    int u, v;
    cin >> u >> v;
    a[u].push_back(v);
    a[v].push_back(u);
  }
  makelca();
  IT.init(n);
  int q;
  cin >> q;
  for (int Q = (0); Q <= (q - 1); Q++) {
    int u, v;
    cin >> u >> v;
    prepQuery(u, v, Q);
  }
  solve(1);
  for (int i = (0); i <= (q - 1); i++) cout << ansQuery[i] << '\n';
}

### Prompt

Please provide a cpp coded solution to the problem described below:

The Finals of the "Russian Code Cup" 2214 will be held in n hotels. Two hotels (let's assume that they are the main hotels), will host all sorts of events, and the remaining hotels will accommodate the participants. The hotels are connected by n - 1 roads, you can get from any hotel to any other one.

The organizers wonder what is the minimum time all the participants need to get to the main hotels, if each participant goes to the main hotel that is nearest to him and moving between two hotels connected by a road takes one unit of time.

The hosts consider various options for the location of the main hotels. For each option help the organizers to find minimal time.

Input

The first line contains an integer n (2 ≤ n ≤ 100000) — the number of hotels. The next n - 1 lines contain two integers each — the numbers of the hotels that have a road between them. Consider hotels are numbered from 1 to n.

The next line contains an integer m (1 ≤ m ≤ 100000) — the number of queries. The following m lines contains two distinct integers each — the numbers of the hotels we assume to be the main.

Output

For each request of the organizers print a single integer — the time that all participants need to reach the main hotels.

Examples

Input

3
2 3
3 1
3
2 1
2 3
3 1


Output

1
1
1


Input

4
1 4
1 2
2 3
3
1 4
1 3
2 3


Output

2
1
2

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
void _print() { cout << '\n'; }
void print() { cout << '\n'; }
template <typename T, typename... Ts>
void _print(const T& value, const Ts&... values) {
  cout << ' ' << value;
  _print(values...);
}
template <typename T, typename... Ts>
void print(const T& value, const Ts&... values) {
  cout << value;
  _print(values...);
}
const int N = 1e5 + 5;
using ll = long long;
struct Query {
  int id;
  pair<int, int> seg1, seg2;
  Query(int _1, pair<int, int> _2, pair<int, int> _3)
      : id(_1), seg1(_2), seg2(_3){};
};
int par[18][N], depth[N], sta[N], en[N], child[N];
int ansQuery[N];
bool done[N];
vector<int> a[N];
int n, Time = 0;
vector<Query> query[N];
const int INF = 1e9;
class ITrangeMaxMin {
 private:
  int n, f[4 * N];
  void init(int k, int l, int r) {
    f[k] = -INF;
    if (l == r) return;
    init(k * 2, l, ((l + r) / 2));
    init(k * 2 + 1, ((l + r) / 2) + 1, r);
  }
  void update(int k, int l, int r, int pos, int val) {
    if (r < pos || pos < l || l > r) return;
    if (pos <= l && r <= pos) {
      f[k] = val;
      return;
    }
    update(k * 2, l, ((l + r) / 2), pos, val);
    update(k * 2 + 1, ((l + r) / 2) + 1, r, pos, val);
    f[k] = max(f[k * 2], f[k * 2 + 1]);
  }
  int get(int k, int l, int r, int L, int R) {
    if (r < L || R < l || l > r) return -INF;
    if (L <= l && r <= R) return f[k];
    return max(get(k * 2, l, ((l + r) / 2), L, R),
               get(k * 2 + 1, ((l + r) / 2) + 1, r, L, R));
  }

 public:
  void init(int _n) {
    n = _n;
    init(1, 0, n + 1);
  }
  int get(int l, int r) { return get(1, 0, n + 1, l, r); };
  void update(int pos, int val) { update(1, 0, n + 1, pos, val); };
} IT;
void pdfs(int u, int p) {
  par[0][u] = p;
  sta[u] = ++Time;
  for (auto v : a[u]) {
    if (v != p) {
      depth[v] = depth[u] + 1;
      pdfs(v, u);
    }
  }
  en[u] = Time;
}
void dfsCen(int u, int p) {
  child[u] = 1;
  for (auto v : a[u]) {
    if (v != p && !done[v]) {
      dfsCen(v, u);
      child[u] += child[v];
    }
  }
}
struct custom_hash {
  static unsigned long long splitmix64(unsigned long long x) {
    x += 0x9e3779b97f4a7c15;
    x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
    x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
    return x ^ (x >> 31);
  }
  size_t operator()(pair<int, int> x) const {
    static const unsigned long long FIXED_RANDOM1 =
        chrono::steady_clock::now().time_since_epoch().count();
    static const unsigned long long FIXED_RANDOM2 =
        chrono::steady_clock::now().time_since_epoch().count();
    return hash<unsigned long long>()(splitmix64(x.first + FIXED_RANDOM1) ^
                                      splitmix64(x.second + FIXED_RANDOM2));
  }
};
using hashmap = unordered_map<pair<int, int>, int, custom_hash>;
hashmap cache;
int lca(int p, int q) {
  if (depth[p] < depth[q]) swap(p, q);
  if (cache.find({p, q}) != cache.end()) return cache[{p, q}];
  for (int i = (17); i >= (0); i--) {
    if (depth[par[i][p]] >= depth[q]) p = par[i][p];
  }
  if (p == q) return cache[{p, q}] = p;
  for (int i = (17); i >= (0); i--) {
    if (par[i][p] != par[i][q]) p = par[i][p], q = par[i][q];
  }
  return cache[{p, q}] = par[0][p];
}
int jump(int p, int d) {
  for (int i = (0); i <= (17); i++)
    if (((d >> i) & 1)) p = par[i][p];
  return p;
}
int jumpTow(int u, int d, int v) {
  int p = lca(u, v);
  int dx = depth[u] - depth[p] + depth[v] - depth[p];
  if (d < depth[u] - depth[p])
    return jump(u, d);
  else
    return jump(v, dx - d);
}
void makelca() {
  pdfs(1, 1);
  for (int i = (1); i <= (17); i++) {
    for (int j = (1); j <= (n); j++) {
      par[i][j] = par[i - 1][par[i - 1][j]];
    }
  }
}
void prepQuery(int u, int v, int id) {
  if (depth[u] < depth[v]) swap(u, v);
  int p = lca(u, v);
  int d = depth[u] - depth[p] + depth[v] - depth[p];
  auto sep = jumpTow(u, d / 2, v);
  if (v != p && sep == p) sep = jumpTow(u, d / 2 - 1, v);
  query[u].push_back({id, {sta[sep], en[sep]}, {sta[sep], en[sep]}});
  query[v].push_back({id, {1, sta[sep] - 1}, {en[sep] + 1, n}});
}
int findCen(int u) {
  dfsCen(u, u);
  int sz = child[u];
  while (true) {
  up:
    for (auto v : a[u]) {
      if (child[v] < child[u] && child[v] * 2 > sz) {
        u = v;
        goto up;
      }
    }
    return u;
  }
}
void dfsMod(int u, int p, int d, int type) {
  for (auto v : a[u]) {
    if (v == p || done[v]) continue;
    dfsMod(v, u, d + 1, type);
  }
  if (type == 1)
    IT.update(sta[u], d);
  else
    IT.update(sta[u], -INF);
}
void handleQuery(int u, int d) {
  if (query[u].empty()) return;
  for (auto cur : query[u]) {
    auto& ret = ansQuery[cur.id];
    ret = max(ret, IT.get(cur.seg1.first, cur.seg1.second) + d);
    ret = max(ret, IT.get(cur.seg2.first, cur.seg2.second) + d);
  }
}
void dfsSolve(int u, int p, int d) {
  for (auto v : a[u]) {
    if (v == p || done[v]) continue;
    dfsSolve(v, u, d + 1);
  }
  handleQuery(u, d);
}
void solve(int u) {
  u = findCen(u);
  dfsMod(u, u, 0, 1);
  handleQuery(u, 0);
  for (auto v : a[u]) {
    if (done[v]) continue;
    dfsMod(v, u, 1, -1);
    dfsSolve(v, u, 1);
    dfsMod(v, u, 1, 1);
  }
  dfsMod(u, u, u, -1);
  done[u] = true;
  for (auto v : a[u]) {
    if (!done[v]) solve(v);
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n;
  for (int i = (1); i <= (n - 1); i++) {
    int u, v;
    cin >> u >> v;
    a[u].push_back(v);
    a[v].push_back(u);
  }
  makelca();
  IT.init(n);
  int q;
  cin >> q;
  for (int Q = (0); Q <= (q - 1); Q++) {
    int u, v;
    cin >> u >> v;
    prepQuery(u, v, Q);
  }
  solve(1);
  for (int i = (0); i <= (q - 1); i++) cout << ansQuery[i] << '\n';
}

```