#include <bits/stdc++.h>
using namespace std;
#define IC isdigit(c)
#define GC c=getchar()
void rd(auto &x) { bool f = 0; x = 0; int GC;
for (; !IC; GC) f |= c == '-';
for (; IC; GC) x = x * 10 + c - 48;
f ? (x = -x) : 0;
}
void rd(auto &x, auto &...y) { rd(x); rd(y...); }
#define U(i,l,r) for (int i(l),END##i(r); i<=END##i; ++i)
#define D(i,l,r) for (int i(l),END##i(r); i>=END##i; --i)
#define ms(x, v) memset(x, v, sizeof(x))
#define il __attribute__((always_inline))
#define vc vector
#define pb push_back
#define eb emplace_back
using ll = long long;
const int N = 500005;
int n; vc<int> g[N];
int siz[N], fa[N], dep[N], hson[N]; vc<int> hok[N];
void dfs1(int u, int f) {
siz[u] = 1; fa[u] = f; dep[u] = dep[f] + 1;
hok[dep[u]].pb(u);
for (int v : g[u]) if (v != f) {
dfs1(v, u);
siz[u] += siz[v];
if (siz[v] > siz[hson[u]]) hson[u] = v;
}
}
int top[N], dfn[N], mp[N], dfp;
void dfs2(int u, int f, int t) {
top[u] = t; dfn[u] = ++dfp; mp[dfp] = u;
if (hson[u])
dfs2(hson[u], u, t);
for (int v : g[u]) if (v != hson[u] && v != f)
dfs2(v, u, v);
}
int qlca(int u, int v) {
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
u = fa[top[u]];
}
return dep[u] < dep[v] ? u : v;
}
int dr[N], dl[N];
int get(int *fa, int p) { for (; p != fa[p]; p = fa[p] = fa[fa[p]]); return p; }
void init() {
U (i, 1, n) dr[i] = dl[i] = i;
}
bool merge(int i, int j) {
if (get(dr, i) == get(dr, j)) return 0;
dr[get(dr, i)] = get(dr, j);
dl[get(dl, j)] = get(dl, i);
return 1;
}
using pii = pair<int, int>;
struct seg1 {
#define mid ((l + r) >> 1)
#define ls (p << 1)
#define rs (ls | 1)
#define arg int p = 1, int l = 1, int r = n
#define L ls, l, mid
#define R rs, mid + 1, r
int tr[N * 4];
void up(int p) { tr[p] = max(tr[ls], tr[rs]); }
void build(arg) {
tr[p] = -1e9;
if (l == r) return;
build(L);
build(R);
}
void insert(int x, int v, arg) {
if (l == r) {
tr[p] = max(tr[p], v);
return;
}
(x <= mid) ? insert(x, v, L) : insert(x, v, R);
up(p);
}
int query(int b, int e, arg) {
if (b <= l && e >= r) return tr[p];
int v = -1e9;
if (b <= mid) v = query(b, e, L);
if (e > mid) v = max(v, query(b, e, R));
return v;
}
} sl, sr, sg;
array<int, 3> qry[N]; int q, ans[N];
vc<array<int, 3>> hk[N], hv[N];
bool in(int u, int v) {
if (u < 1 || u > n) return 0;
return dfn[u] >= dfn[v] && dfn[u] < dfn[v] + siz[v];
}
tuple<int, int, int> add(int u, int r) {
int succ = 0;
if (in(u + 1, r))
succ |= merge(u, u + 1);
if (in(u - 1, r))
succ |= merge(u - 1, u);
int x = get(dl, u), y = get(dr, u);
return {succ, x, y};
}
void check(int d, int x, int y) {
hv[y - x + 1].pb({d, x, y});
}
template <bool flag> struct st {
int st[19][N];
void init(int *f) {
U (i, 1, n) st[0][i] = f[i];
U (k, 0, __lg(n) - 1) {
U (i, 1, n - (1 << k + 1) + 1) {
if (flag) st[k + 1][i] = max(st[k][i], st[k][i + (1 << k)]);
else st[k + 1][i] = min(st[k][i], st[k][i + (1 << k)]);
}
}
}
int query(int l, int r) {
int b = __lg(r - l + 1);
if (flag) return max(st[b][l], st[b][r - (1 << b) + 1]);
else return min(st[b][l], st[b][r - (1 << b) + 1]);
}
};
st<0> mn; st<1> mx;
int main() {
freopen("query.in", "r", stdin);
freopen("query.out", "w", stdout);
rd(n);
U (i, 2, n) {
int u, v; rd(u, v);
g[u].pb(v); g[v].pb(u);
}
dfs1(1, 0);
dfs2(1, 0, 1);
init();
mn.init(dfn);
mx.init(dfn);
rd(q);
sl.build();
sr.build();
U (i, 1, q) {
auto &[l, r, k] = qry[i];
rd(l, r, k);
hk[k].pb({l, r, i});
int u = mp[mn.query(l, r)], v = mp[mx.query(l, r)];
ans[i] = dep[qlca(u, v)];
}
D (d, n, 1) if (hok[d].size()) {
for (int u : hok[d]) {
auto [succ, x, y] = add(u, u);
check(d, x, y);
if (!hson[u])
continue;
U (i, dfn[hson[u]] + siz[hson[u]], dfn[u] + siz[u] - 1) {
int v = mp[i];
tie(succ, x, y) = add(v, u);
if (succ) {
check(d, x, y);
}
}
}
}
clog << "fin" << endl;
D (l, n, 1) {
for (auto [v, x, y] : hv[l]) {
sl.insert(x, v);
sr.insert(y, v);
}
for (auto [x, y, id] : hk[l]) {
int v1 = sl.query(x, y - l + 1),
v2 = sr.query(x + l - 1, y);
ans[id] = max({ans[id], v1, v2});
}
}
U (i, 1, q)
printf("%d\n", ans[i]);
}