#include<bits/stdc++.h>
using namespace std;

#define LL long long

void read(LL &x){
	scanf("%lld",&x);
}

void write(LL x,LL op=1){
	if(!op) printf("%lld ",x);
	else printf("%lld\n",x);
}

const LL N=5e5+10;

LL n,q,l[N],r[N],k[N];

vector<LL> g[N];

namespace subtask1{
	const LL M=22;
	int fmx[N][M],fmn[N][M],fd[N<<1][M],lg[N<<1],dfn[N],s[N<<1],cnt,dep[N];
	pair<LL,LL> ask(LL l,LL r){
		return {min(fmn[l][lg[r-l+1]],fmn[r-(1<<lg[r-l+1])+1][lg[r-l+1]]),max(fmx[l][lg[r-l+1]],fmx[r-(1<<lg[r-l+1])+1][lg[r-l+1]])};
	}
	LL query(LL l,LL r){
		return min(fd[l][lg[r-l+1]],fd[r-(1<<lg[r-l+1])+1][lg[r-l+1]]);
	}
	LL calc(LL l,LL r){
		pair<LL,LL> gt=ask(l,r);
		return query(gt.first,gt.second);
	}
	void dfs(LL u,LL fa){
		if(!fa) dep[u]=1;
		else dep[u]=dep[fa]+1;
		s[++cnt]=u;
		dfn[u]=cnt;
		for(LL v:g[u]){
			if(v==fa) continue;
			dfs(v,u);
			s[++cnt]=u;
			dfn[u]=cnt;
		}
	}
	void solve(){
		for(LL i=2;i<(N<<1);i++) lg[i]=lg[i>>1]+1;
		dfs(1,0);
		for(LL i=n;i>=1;i--){
			fmn[i][0]=fmx[i][0]=dfn[i];
			for(LL j=1;j<M;j++){
				if(i+(1<<j)-1>n) break;
				fmn[i][j]=min(fmn[i][j-1],fmn[i+(1<<(j-1))][j-1]);
				fmx[i][j]=max(fmx[i][j-1],fmx[i+(1<<(j-1))][j-1]);
			}
		}
		for(LL i=cnt;i>=1;i--){
			fd[i][0]=dep[s[i]];
			for(LL j=1;j<M;j++){
				if(i+(1<<j)-1>cnt) break;
				fd[i][j]=min(fd[i][j-1],fd[i+(1<<(j-1))][j-1]);
			}
		}
		for(LL i=1;i<=q;i++){
			LL ans=0;
			for(LL j=l[i];j<=r[i]-k[i]+1;j++) ans=max(ans,calc(j,j+k[i]-1));
			write(ans);
		}
	}
}

namespace subtask2{
	LL dep[N],ys[N];
	void dfs(LL u,LL fa){
		if(!fa) dep[u]=1;
		else dep[u]=dep[fa]+1;
		ys[dep[u]]=u;
		for(LL v:g[u]){
			if(v==fa) continue;
			dfs(v,u);
		}
	}
	struct Tree{
		LL mx;
		LL lf;
		LL rt;
		LL len;
	}tree[N<<2];
	void merge(Tree &nw,Tree lf,Tree rt){
		nw.lf=lf.lf;
		if(lf.lf==lf.len) nw.lf+=rt.lf;
		nw.rt=rt.rt;
		if(rt.rt==rt.len) nw.rt+=lf.rt;
		nw.mx=max({lf.mx,rt.mx,lf.rt+rt.lf});
		nw.len=lf.len+rt.len;
	}
	void pushup(LL w){
		merge(tree[w],tree[w<<1],tree[w<<1|1]);
	}
	void build(LL l,LL r,LL w){
		if(l==r){
			tree[w].len=1;
			return ;
		}
		LL mid=l+r>>1;
		build(l,mid,w<<1);
		build(mid+1,r,w<<1|1);
		pushup(w);
	}
	void modify(LL l,LL r,LL w,LL x,LL v){
		if(l==r){
			tree[w].lf=tree[w].rt=tree[w].mx=v;
			return ;
		}
		LL mid=l+r>>1;
		if(mid>=x) modify(l,mid,w<<1,x,v);
		else modify(mid+1,r,w<<1|1,x,v);
		pushup(w);
	}
	Tree query(LL l,LL r,LL w,LL lx,LL rx){
//		if(lx>rx) return 0;
		if(l>=lx&&r<=rx) return tree[w];
		LL mid=l+r>>1;
		if(mid<lx) return query(mid+1,r,w<<1|1,lx,rx);
		if(mid>=rx) return query(l,mid,w<<1,lx,rx);
		Tree nw;
		merge(nw,query(l,mid,w<<1,lx,rx),query(mid+1,r,w<<1|1,lx,rx));
		return nw;
	}
	LL ans[N];
	void ptt(LL L,LL R,vector<LL> nw){
		if(L==R){
			for(LL x:nw) ans[x]=L-1;
			return ;
		}
		vector<LL> lf,rt;
		LL mid=L+R>>1;
		for(LL i=mid;i<=R;i++) modify(1,n,1,ys[i],1);
		for(LL x:nw){
			if(query(1,n,1,l[x],r[x]).mx>=k[x]){
				rt.push_back(x);
			}
			else lf.push_back(x);
		}
		ptt(L,mid,lf);
		for(LL i=mid;i<=R;i++) modify(1,n,1,ys[i],-1);
		ptt(mid+1,R,rt);
	}
	void solve(){
		build(1,n,1);
		dfs(1,0);
		vector<LL> nw;
		for(LL i=1;i<=q;i++) nw.push_back(i);
		ptt(1,n,nw);
		for(LL i=1;i<=q;i++){
			write(ans[i]);
		}
	}
}

bool checkB(){
	for(LL i=1;i<=q;i++){
		if(r[i]-l[i]+1!=k[i]) return false;
	}
	return true;
}

void solve(){
	read(n);
	for(LL i=1;i<n;i++){
		LL u,v;
		read(u),read(v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	read(q);
	for(LL i=1;i<=q;i++) read(l[i]),read(r[i]),read(k[i]);
//	if(checkB()){
//		printf("Yes\n");
//		return ;
//	}
	if((n<=5000&&q<=5000)||checkB()){
		subtask1::solve();
		return ;
	}
//	write(1);
	subtask2::solve();
}

int main(){
	freopen("query.in","r",stdin);
	freopen("query.out","w",stdout);
	LL T=1;
//	read(T);
	while(T--){
		solve();
	}
	return 0;
}

