#include <bits/stdc++.h>
#define _rep(i_, a_, b_) for(int i_ = a_; i_ <= b_; ++i_)
#define mid ((L + R) >> 1)
int in(void) {
int x = 0, c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
return x;
}
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int kN = 505000, kM = 21005000;
int n;
vector<int> g[kN];
struct Node {
int L, R, ch[2], ful;
} t[kM]; int nc;
struct Point {
int l, r, k;
int getlen(void) const { return r - l + 1; }
bool operator < (const Point &a) {
if(l != a.l || r != a.r) return l != a.l ? l < a.l : r < a.r;
return k > a.k;
}
};
struct Query {
int l, r, k, id;
} q[kN]; int ans[kN];
vector<Point> R, Q;
vector<pii> tmp;
void pushup(int x) {
Node &a = t[t[x].ch[0]], &b = t[t[x].ch[1]];
t[x].ful = a.ful && b.ful;
if(a.R != -1 && b.L != -1) tmp.emplace_back(a.R, b.L);
if(a.ful && b.L != -1) t[x].L = b.L; else t[x].L = a.L;
if(b.ful && a.R != -1) t[x].R = a.R; else t[x].R = b.R;
}
void modify(int &x, int L, int R, int p) {
x = ++nc;
if(L == R) { t[x].L = t[x].R = L, t[x].ful = 1; return; }
p <= mid ? modify(t[x].ch[0], L, mid, p) : modify(t[x].ch[1], mid + 1, R, p);
pushup(x);
}
int merge(int x, int y) {
if(!x || !y) return x + y;
t[x].ch[0] = merge(t[x].ch[0], t[y].ch[0]);
t[x].ch[1] = merge(t[x].ch[1], t[y].ch[1]);
pushup(x); return x;
}
int rt[kN];
void dfs(int u, int f, int dep) {
modify(rt[u], 1, n, u);
for(auto &v : g[u]) if(v != f) dfs(v, u, dep + 1);
for(auto &v : g[u]) if(v != f) rt[u] = merge(rt[u], rt[v]);
for(auto &v : tmp) R.push_back(Point{v.first, v.second, dep});
R.push_back(Point{u, u, dep});
tmp.clear();
}
int mx[kN << 2];
void modifymx(int x, int L, int R, int p, int y) {
mx[x] = max(mx[x], y);
if(L == R) return; p <= mid ? modifymx(x << 1, L, mid, p, y) : modifymx(x << 1 | 1, mid + 1, R, p, y);
}
int querymx(int x, int L, int R, int l, int r) {
if(l <= L && R <= r) return mx[x];
if(r <= mid) return querymx(x << 1, L, mid, l, r);
if(mid < l) return querymx(x << 1 | 1, mid + 1, R, l, r);
return max(querymx(x << 1, L, mid, l, r), querymx(x << 1 | 1, mid + 1, R, l, r));
}
int main() {
freopen("query.in", "r", stdin);
freopen("query.out", "w", stdout);
t[0].L = -1, t[0].R = -1;
n = in();
_rep(i,2,n) {
int u = in(), v = in();
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0, 1);
sort(R.begin(), R.end());
for(auto &v : R) if(Q.empty() || Q.back().l != v.l || Q.back().r != v.r) Q.push_back(v);
int m = in();
_rep(i,1,m) q[i].l = in(), q[i].r = in(), q[i].k = in(), q[i].id = i;
sort(q + 1, q + 1 + m, [](const Query &a, const Query &b) { return a.l < b.l; });
sort(Q.begin(), Q.end(), [](const Point &a, const Point &b) { return a.l < b.l; });
int ptr = -1;
_rep(i,1,m) {
while(ptr + 1 < Q.size() && Q[ptr + 1].l <= q[i].l) ++ptr, modifymx(1, 1, n, Q[ptr].r, Q[ptr].k);
ans[q[i].id] = max(ans[q[i].id], querymx(1, 1, n, q[i].l + q[i].k - 1, n));
}
ptr = -1, memset(mx, 0, sizeof(mx));
sort(q + 1, q + 1 + m, [](const Query &a, const Query &b) { return a.k > b.k; });
sort(Q.begin(), Q.end(), [](const Point &a, const Point &b) { return a.getlen() > b.getlen(); });
_rep(i,1,m) {
while(ptr + 1 < Q.size() && Q[ptr + 1].getlen() >= q[i].k) ++ptr, modifymx(1, 1, n, Q[ptr].r, Q[ptr].k);
ans[q[i].id] = max(ans[q[i].id], querymx(1, 1, n, q[i].l + q[i].k - 1, q[i].r));
}
ptr = -1, memset(mx, 0, sizeof(mx));
_rep(i,1,m) {
while(ptr + 1 < Q.size() && Q[ptr + 1].getlen() >= q[i].k) ++ptr, modifymx(1, 1, n, Q[ptr].l, Q[ptr].k);
ans[q[i].id] = max(ans[q[i].id], querymx(1, 1, n, q[i].l, q[i].r - q[i].k + 1));
}
_rep(i,1,m) printf("%d\n", ans[i]);
return 0;
}