#include<bits/stdc++.h>
using namespace std;
const int maxn=500000;
int n,m;
int head[maxn+5],nxt[2*maxn+5],to[2*maxn+5],tot;
int father[maxn+5],depth[maxn+5],siz[maxn+5],top[maxn+5],son[maxn+5];
void AddEdge(int u,int v){
to[++tot]=v;
nxt[tot]=head[u];
head[u]=tot;
}
void DFS1(int p,int fa){
siz[p]=1;
father[p]=fa;
depth[p]=depth[fa]+1;
for(int i=head[p];i;i=nxt[i]){
if(to[i]!=fa){
DFS1(to[i],p);
siz[p]+=siz[to[i]];
if(siz[to[i]]>=siz[son[p]]){
son[p]=to[i];
}
}
}
}
void DFS2(int p,int fa,int tp){
top[p]=tp;
if(son[p]){
DFS2(son[p],p,tp);
}
for(int i=head[p];i;i=nxt[i]){
if(to[i]!=fa&&to[i]!=son[p]){
DFS2(to[i],p,to[i]);
}
}
}
int LCA(int u,int v){
while(top[u]!=top[v]){
if(depth[top[u]]>=depth[top[v]]){
u=father[top[u]];
}
else{
v=father[top[v]];
}
}
if(depth[u]>depth[v]){
return v;
}
else{
return u;
}
}
int D[maxn+5],Lg2[maxn+5];
int ST[maxn+5][21],ind[maxn+5][21];
int SD[maxn+5][21];
int QueryMin(int l,int r){
int len=Lg2[r-l+1];
return min(ST[l][len],ST[r-(1<<len)+1][len]);
}
int QueryMinInd(int l,int r){
int len=Lg2[r-l+1];
if(ST[l][len]<ST[r-(1<<len)+1][len]){
return ind[l][len];
}
else{
return ind[r-(1<<len)+1][len];
}
}
int QueryDepth(int l,int r){
int len=Lg2[r-l+1];
return max(SD[l][len],SD[r-(1<<len)+1][len]);
}
struct Query{
int l,r,k,id;
}Q[maxn+5];
struct node{
int l,r,k,value,id;
};node asd[3*maxn+5];int sizz;
bool comp1(node u,node v){
return u.l>v.l;
}
bool comp2(node u,node v){
return u.r<v.r;
}
int answer[maxn+5];
void Solve(int l,int r){
asd[++sizz]={2*l,r,r-l+1,QueryMin(l,r),-1};
if(l==r)return;
int minid=QueryMinInd(l,r);
if(l!=minid)Solve(l,minid-1);
if(r!=minid)Solve(minid+1,r);
}
struct BIT{
int T[maxn+5];
void Modify(int p,int c){
for(int i=p;i;i-=i&-i){
T[i]=max(T[i],c);
}
}
void Clear(int p){
for(int i=p;i;i-=i&-i){
T[i]=0;
}
}
int Query(int p){
int res=0;
for(int i=p;i<=n;i+=i&-i){
res=max(res,T[i]);
}
return res;
}
}bit;
void CDQ(int l,int r){
if(r==l+1)return;
int mid=(l+r)>>1;
CDQ(l,mid);
CDQ(mid,r);
sort(asd+l,asd+mid,comp2);
sort(asd+mid,asd+r,comp2);
for(int i=mid,j=l;i<r;i++){
if(asd[i].id==-1)continue;
while(j<mid&&asd[j].r<asd[i].r&&asd[j].l>asd[i].l){
if(asd[j].value!=-1){
bit.Modify(asd[j].k,asd[j].value);
}
j++;
}
answer[asd[i].id]=max(answer[asd[i].id],bit.Query(asd[i].k));
}
for(int i=l;i<mid;i++){
if(asd[i].value!=-1){
bit.Clear(asd[i].k);
}
}
}
signed main(){
freopen("query.in","r",stdin);
freopen("query.out","w",stdout);
int u,v,w;
scanf("%d",&n);
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
AddEdge(u,v);
AddEdge(v,u);
}
DFS1(1,0);
DFS2(1,0,1);
for(int i=1;i<n;i++){
ST[i][0]=D[i]=depth[LCA(i,i+1)];
ind[i][0]=i;
}
for(int i=1;i<=n;i++){
SD[i][0]=depth[i];
}
for(int i=2;i<=n;i++){
Lg2[i]=Lg2[i/2]+1;
}
for(int i=1;(1<<i)<n;i++){
for(int j=1;j+(1<<i)-1<n;j++){
if(ST[j][i-1]<ST[j+(1<<(i-1))][i-1]){
ST[j][i]=ST[j][i-1];
ind[j][i]=ind[j][i-1];
}
else{
ST[j][i]=ST[j+(1<<(i-1))][i-1];
ind[j][i]=ind[j+(1<<(i-1))][i-1];
}
}
}
for(int i=1;(1<<i)<=n;i++){
for(int j=1;j+(1<<i)-1<=n;j++){
SD[j][i]=max(SD[j][i-1],SD[j+(1<<(i-1))][i-1]);
}
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&Q[i].l,&Q[i].r,&Q[i].k);
Q[i].id=i;
if(Q[i].k!=1){
Q[i].r--;
Q[i].k--;
answer[i]=max(QueryMin(Q[i].l,Q[i].l+Q[i].k-1),QueryMin(Q[i].r-Q[i].k+1,Q[i].r));
asd[++sizz]={2*Q[i].l-1,Q[i].r+1,Q[i].k,-1,Q[i].id};
}
else{
answer[i]=QueryDepth(Q[i].l,Q[i].r);
}
}
Solve(1,n-1);
sort(asd+1,asd+sizz+1,comp1);
CDQ(1,sizz+1);
for(int i=1;i<=m;i++){
printf("%d\n",answer[i]);
}
}