#include <fstream>
#include <vector>
#include <algorithm>
#include <cassert>
#define lson x*2
#define rson x*2+1
using namespace std;
ifstream cin ("query.in");
ofstream cout ("query.out");
const int MAXN = 5e5+10;
struct Tree
{
int fa[MAXN][20];
int dep[MAXN];
vector <int> edges[MAXN];
int c = 0;
void add_edge (int x,int y)
{
edges[x].emplace_back(y);
edges[y].emplace_back(x);
}
void dfs1 (int x,int f)
{
fa[x][0]=f;
dep[x]=dep[f]+1;
for (auto i:edges[x])
{
if (i!=f)
{
dfs1(i,x);
}
}
}
void build (int n)
{
for (int j=1;j<=18;j++)
{
for (int i=1;i<=n;i++)
{
fa[i][j]=fa[fa[i][j-1]][j-1];
}
}
}
int lca (int x,int y)
{
if (dep[x]>dep[y])
{
swap(x,y);
}
for (int j=18;j>=0;j--)
{
if (dep[fa[y][j]]>=dep[x])
{
y=fa[y][j];
}
}
for (int j=18;j>=0;j--)
{
if (fa[x][j]!=fa[y][j])
{
x=fa[x][j],y=fa[y][j];
}
}
if (x==y)
{
return x;
}
else
{
return fa[x][0];
}
}
}T;
int n;
struct BIT
{
int c[MAXN];
int tag[MAXN];
int t;
void build ()
{
t++;
}
void update (int p,int v)
{
for (;p;p-=p&(-p))
{
if (tag[p]!=t)
{
tag[p]=t;
c[p]=-1e9;
}
c[p]=max(c[p],v);
}
}
int query (int p)
{
int res = -1e9;
for (;p<=n;p+=p&(-p))
{
if (tag[p]==t)
{
res=max(res,c[p]);
}
}
return res;
}
}TTT;
struct STree
{
int tr[4*MAXN];
void build (int x,int l,int r)
{
tr[x]=-1e9;
if (l==r)
{
return;
}
int mid = (l+r)/2;
build(lson,l,mid);
build(rson,mid+1,r);
}
void pushup (int x)
{
tr[x]=max(tr[lson],tr[rson]);
}
void update (int x,int l,int r,int p,int v)
{
if (l==r)
{
tr[x]=max(tr[x],v);
return;
}
int mid = (l+r)/2;
if (p<=mid)
{
update(lson,l,mid,p,v);
}
else
{
update(rson,mid+1,r,p,v);
}
pushup(x);
}
void clear (int x,int l,int r,int p)
{
tr[x]=-1e9;
if (l==r)
{
return;
}
int mid = (l+r)/2;
if (p<=mid)
{
clear(lson,l,mid,p);
}
else
{
clear(rson,mid+1,r,p);
}
}
int query (int x,int l,int r,int L,int R)
{
if (L<=l and r<=R)
{
return tr[x];
}
int res = -1e9;
int mid = (l+r)/2;
if (L<=mid)
{
res=max(res,query(lson,l,mid,L,R));
}
if (R>mid)
{
res=max(res,query(rson,mid+1,r,L,R));
}
return res;
}
}TT;
int d[MAXN];
int res[MAXN];
int fa[MAXN],L[MAXN],R[MAXN];
vector <int> gzd[MAXN];
struct Node
{
int x,y,z,v;
int op;
}nds[MAXN*2];
int find (int x)
{
if (x==fa[x])
{
return x;
}
return fa[x]=find(fa[x]);
}
bool tag[MAXN];
void merge (int x,int y)
{
x=find(x),y=find(y);
fa[x]=y;
L[y]=min(L[x],L[y]);
R[y]=max(R[x],R[y]);
}
int c= 0;
void solve (int l,int r)
{
if (l==r)
{
return;
}
int mid = (l+r)/2;
solve(l,mid);
solve(mid+1,r);
sort(nds+l,nds+mid+1,[](Node a,Node b){if (a.x!=b.x) return a.x<b.x; return a.y>b.y;});
sort(nds+mid+1,nds+r+1,[](Node a,Node b){if (a.x!=b.x) return a.x<b.x; return a.y>b.y;});
TTT.build();
int j = mid+1;
for (int i=l;i<=mid;i++)
{
while (j<=r and nds[j].x<nds[i].x)
{
if (nds[j].op==1)
{
res[nds[j].v]=max(res[nds[j].v],TTT.query(nds[j].y));
}
j++;
}
if (nds[i].op==0)
{
TTT.update(nds[i].y,nds[i].v);
}
}
for (;j<=r;j++)
{
if (nds[j].op==1)
{
res[nds[j].v]=max(res[nds[j].v],TTT.query(nds[j].y));
}
}
}
void solve (void)
{
sort(nds+1,nds+c+1,[](Node a,Node b){if (a.z!=b.z) return a.z>b.z; else return a.op<b.op;});
solve(1,c);
return;
}
int main ()
{
cin.tie(0);
cin>>n;
for (int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
T.add_edge(u,v);
}
T.dfs1(1,0);
T.build(n);
for (int i=1;i<=n;i++)
{
TT.update(1,1,n,i,T.dep[i]);
}
for (int i=1;i<n;i++)
{
d[i]=T.dep[T.lca(i,i+1)];
gzd[d[i]].emplace_back(i);
}
for (int i=1;i<=n;i++)
{
fa[i]=i;
L[i]=R[i]=i;
}
for (int i=n;i>=1;i--)
{
for (auto x:gzd[i])
{
tag[x]=1;
if(x>=2 and tag[x-1])
{
merge(x,x-1);
}
if (x<n and tag[x+1])
{
merge(x,x+1);
}
x = find(x);
int len = R[x]-L[x]+1;
nds[++c].x=L[x];
nds[c].y=R[x];
nds[c].z=len;
nds[c].v=i;
nds[c].op=0;
}
}
int Q;
cin>>Q;
for (int i=1;i<=Q;i++)
{
int l,r,k;
cin>>l>>r>>k;
if (k==1)
{
res[i]=TT.query(1,1,n,l,r);
}
else if (k>r-l+1)
{
res[i]=0;
}
else
{
r--;
nds[++c].x=max(1,r-k+2);
nds[c].y=min(n,k+l-2);
nds[c].z=k-1;
nds[c].v=i;
nds[c].op=1;
}
}
solve();
for (int i=1;i<=Q;i++)
{
cout<<res[i]<<'\n';
}
}