#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N=5e5+5;
int n,dfn[N],cnt,q,ans1=0,dep[N],siz[N],rt=1,f[N],in_[N],ans[N];
struct ooo
{
	int id;
	int l;
	int r;
	int k;
}p[N],pos[N];
int tr[N];
vector<int>a[N];
bool cmp1(ooo x,ooo y)
{
	return x.k>y.k;
}
void dfs(int u,int fa)
{
	dfn[u]=++cnt;
	f[u]=fa;
	dep[u]=dep[fa]+1;
	siz[u]=1;
	for(int i=0;i<a[u].size();i++)
	{
		int v=a[u][i];
		if(v==fa)
		continue;
		dfs(v,u);
		siz[u]+=siz[v];
	}
}
int get_tr(int x)
{
	int s=0;
	for(;x;x-=x&(-x))
	s+=tr[x];
	return s;
}
void add_tr(int x,int val)
{
	for(;x<=n;x+=x&(-x))
	tr[x]+=val;
}
void check(int u,int c)
{
	int x=get_tr(dfn[u]+siz[u]-1)-get_tr(dfn[u]-1);
	if(x==c)
	{
		if(dep[u]>=ans1)
		rt=u;
		ans1=max(ans1,dep[u]);
	}
	else
	return;
	
	for(int i=0;i<a[u].size();i++)
	{
		int v=a[u][i];
		if(v==f[u])
		continue;
		check(v,c);
	}
}
//bool lian()
//{
//	int s=0;
//	for(int i=1;i<=n;i++)
//	{
//		s+=in_[i];
//	}
//	if(s>=2)
//	return 0;
//	return 1;
//}
void dao(int u)
{
//	cout<<u<<endl;
	for(int i=0;i<a[u].size();i++)
	{
		int v=a[u][i];
		if(v==f[u])
		continue;
		dao(v);
	}
	pos[u].k=pos[u+1].k+1;
	pos[u].id=u;
}
int maxl[N*8],maxl2[N*8];
void add_xian_tree(int l,int r,int z,int tar,int val)
{
	if(l==r)
	{
		maxl[z]=val;
		return;
	}
	int mid=(l+r)>>1;
	if(tar<=mid)
	add_xian_tree(l,mid,z*2,tar,val);
	else
	add_xian_tree(mid+1,r,z*2+1,tar,val);
	maxl[z]=max(maxl[z*2],maxl[z*2+1]);
}
int get_xian_tree(int l,int r,int find_l,int find_r,int z)
{
	if(find_l<=l&&r<=find_r)
	{
		return maxl[z];
	}
	int mid=(l+r)>>1,val1=0,val2=0;
	if(find_l<=mid)
	val1=get_xian_tree(l,mid,find_l,find_r,z*2);
	if(mid<find_r)
	val2=get_xian_tree(mid+1,r,find_l,find_r,z*2+1);
	return max(val1,val2);
}


void add_xian_tree2(int l,int r,int z,int tar,int val)
{
	if(l==r)
	{
		maxl2[z]=val;
		return;
	}
	int mid=(l+r)>>1;
	if(tar<=mid)
	add_xian_tree2(l,mid,z*2,tar,val);
	else
	add_xian_tree2(mid+1,r,z*2+1,tar,val);
	maxl2[z]=min(maxl2[z*2],maxl2[z*2+1]);
}
int get_xian_tree2(int l,int r,int find_l,int find_r,int z)
{
	if(find_l<=l&&r<=find_r)
	{
		return maxl2[z];
	}
	int mid=(l+r)>>1,val1=n+1,val2=n+1;
	if(find_l<=mid)
	val1=get_xian_tree2(l,mid,find_l,find_r,z*2);
	if(mid<find_r)
	val2=get_xian_tree2(mid+1,r,find_l,find_r,z*2+1);
	return min(val1,val2);
}
int main()
{
	freopen("query.in","r",stdin);
	freopen("query.out","w",stdout);
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		in_[u]++;
		in_[v]++;
		a[u].push_back(v);
		a[v].push_back(u);
	}
	dfs(1,0);
	scanf("%d",&q);
//	cout<<"a";
	if(n<=5000)
	{
		while(q--)
		{
			int l,r,k;
			scanf("%d%d%d",&l,&r,&k);
			rt=1;
			ans1=0;
			for(int i=0;i<=n;i++)
			tr[i]=0;
			for(int i=l;i<=r;i++)
			{
				add_tr(dfn[i],1);
				if(i>=l+k-1)
				{
					check(rt,k);
					add_tr(dfn[i-k+1],-1);
				}
			}
			printf("%d\n",ans1);
		}	
	}
	else
	{
//		cout<<"aaa";
		for(int i=1;i<=n+1;i++)
		pos[i].k=0,pos[i].id=0;
		dao(1);
		memset(maxl2,0x3f,sizeof(maxl2));
		for(int i=1;i<=n;i++)
		{
			add_xian_tree2(1,n,1,i,dep[i]);
		}
//		for(int i=1;i<=n;i++)
//		{
//			cout<<pos[i].k<<" ";
//		}
//		cout<<endl;
		for(int i=1;i<=q;i++)
		{
			scanf("%d%d%d",&p[i].l,&p[i].r,&p[i].k);
			p[i].id=i;
		}
		sort(p+1,p+q+1,cmp1);
		sort(pos+1,pos+n+1,cmp1);
		int last=1;
		for(int i=1;i<=q;i++)
		{
			while(pos[last].k>=p[i].k)
			{
//				cout<<"a"<<pos[last].id<<" "<<dep[pos[last].id]<<endl;
				add_xian_tree(1,n,1,pos[last].id,dep[pos[last].id]);
				last++;
			}
//			cout<<p[i].l<<" "<<p[i].r-p[i].k+1<<endl;
			int x=get_xian_tree(1,n,p[i].l,p[i].r-p[i].k+1,1);
			int y=get_xian_tree2(1,n,p[i].l,p[i].r,1);
			ans[p[i].id]=max(y,x);
		}
		for(int i=1;i<=q;i++)
		{
			printf("%d\n",ans[i]);
		}
	}
	return 0;
}
