#include <bits/stdc++.h>
using namespace std;
int main() {
static const int maxn = 500010, maxlg = 20;
freopen("query.in", "r", stdin);
freopen("query.out", "w", stdout);
int n; scanf("%d", &n);
static vector<int> G[maxn];
for (int i = 1, u, v; i < n; i++) {
scanf("%d %d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
static int dep[maxn], dfn[maxn];
static int lg[maxn], st[maxlg][maxn], stD[maxlg][maxn];
function<void(int, int)> dfs = [&dfs](const int u, const int fa) {
static int cnt;
st[0][dfn[u] = ++cnt] = dep[fa];
stD[0][u] = dep[u] = dep[fa] + 1;
for (int i : G[u])
if (i != fa)
dfs(i, u);
return;
};
dfs(1, 0);
for (int i = 2; i <= n; i++) lg[i] = lg[i >> 1] + 1;
for (int l = 1; l <= lg[n]; l++)
for (int i = 1; i + (1 << l) - 1 <= n; i++) {
st[l][i] = min(st[l - 1][i], st[l - 1][i + (1 << (l - 1))]);
stD[l][i] = max(stD[l - 1][i], stD[l - 1][i + (1 << (l - 1))]);
}
auto lca = [](int u, int v) {
u = dfn[u], v = dfn[v];
if (u > v) swap(u, v);
int Lg = lg[v - (++u) + 1];
return min(st[Lg][u], st[Lg][v - (1 << Lg) + 1]);
};
static vector<int> cut[maxn];
for (int i = 1; i < n; i++)
cut[lca(i, i + 1)].push_back(i);
struct node { int l, r, d; };
vector<node> S;
for (int d = 1; d <= n; d++) {
static set<pair<int, int>> seg = { make_pair(1, n) };
for (int i : cut[d]) {
auto it = prev(seg.lower_bound(make_pair(i, n + 1)));
auto L = make_pair(it->first, i), R = make_pair(i + 1, it->second);
S.push_back({ it->first, it->second, d });
seg.erase(it), seg.insert(L), seg.insert(R);
}
}
int q; scanf("%d", &q);
struct query { int l, r, k, id; };
static vector<query> Q;
static int ans[maxn];
for (int i = 1, l, r, k; i <= q; i++) {
scanf("%d %d %d", &l, &r, &k);
Q.push_back({ l, r, k, i });
if (k == 1) {
int Lg = lg[r - l + 1];
ans[i] = max(stD[Lg][l], stD[Lg][r - (1 << Lg) + 1]);
}
}
struct SegT {
struct node { int l, r, mx; };
node t[maxn << 2];
static inline int ls(const int u) { return u << 1; }
static inline int rs(const int u) { return u << 1 | 1; }
void build(const int l, const int r, const int u) {
t[u].l = l, t[u].r = r, t[u].mx = 0;
if (l == r) return;
int mid = (l + r) >> 1;
build(l, mid, ls(u));
build(mid + 1, r, rs(u));
return;
}
void insert(const int p, const int u, const int x) {
if (p < t[u].l || t[u].r < p) return;
t[u].mx = max(t[u].mx, x);
if (t[u].l == t[u].r) return;
insert(p, ls(u), x);
insert(p, rs(u), x);
return;
}
int query(const int l, const int r, const int u) {
if (r < t[u].l || t[u].r < l) return 0;
if (l <= t[u].l && t[u].r <= r) return t[u].mx;
return max(query(l, r, ls(u)), query(l, r, rs(u)));
}
};
static SegT t;
t.build(1, n, 1);
sort(S.begin(), S.end(), [](const node x, const node y) { return x.r - x.l > y.r - y.l; });
sort(Q.begin(), Q.end(), [](const query x, const query y) { return x.k > y.k; });
for (int i = 0, j = 0; i < Q.size(); i++) {
while (j < S.size() && S[j].r - S[j].l + 1 >= Q[i].k)
t.insert(S[j].l, 1, S[j].d), j++;
ans[Q[i].id] = max(ans[Q[i].id], t.query(Q[i].l, Q[i].r - Q[i].k + 1, 1));
}
t.build(1, n, 1);
sort(S.begin(), S.end(), [](const node x, const node y) { return x.l < y.l; });
sort(Q.begin(), Q.end(), [](const query x, const query y) { return x.l < y.l; });
for (int i = 0, j = 0; i < Q.size(); i++) {
while (j < S.size() && S[j].l < Q[i].l)
t.insert(S[j].r, 1, S[j].d), j++;
ans[Q[i].id] = max(ans[Q[i].id], t.query(Q[i].l + Q[i].k - 1, n, 1));
}
for (int i = 1; i <= q; i++) printf("%d\n", ans[i]);
return 0;
}