#include <bits/stdc++.h>
using namespace std;
namespace FastRead{
inline char gc()
{
static char buf[1 << 20 | 5], *s = buf, *t = buf;
return s == t && (t = (s = buf) + fread(buf, 1, 1 << 20, stdin), s == t) ? EOF : *s ++ ;
}
template <typename T>
inline void Read(T &x)
{
x = 0;
char ch = gc();
while(ch < '0' || ch > '9') ch = gc();
while('0' <= ch && ch <= '9') x = x * 10 + (ch ^ 48), ch = gc();
}
}
using FastRead::Read;
const int N = 5e5 + 5, K = 19;
int n, m;
int la[N], ne[N * 2], en[N * 2], idx;
int fa[N], dep[N], siz[N], son[N], top[N], in[N], out[N], rnk[N], dfst;
vector<int> intv[N];
struct Point{
int l, r, d, t;
}p[N], q[N];
int ans[N];
struct DSU{
int fa[N], sta[N], tt;
inline void Init()
{
for(int i = 1; i <= n + 1; i ++ ) fa[i] = i;
}
inline int gfa(int i)
{
return i == fa[i] ? i : fa[i] = gfa(fa[i]);
}
inline void Merge(int i, int j)
{
sta[ ++ tt] = i;
fa[i] = j;
}
inline void Clear()
{
for(int i = 1; i <= tt; i ++ ) fa[sta[i]] = sta[i];
tt = 0;
}
};
struct D{
DSU T0, T1;
inline void Init()
{
T0.Init(), T1.Init();
}
inline void Insert(int i)
{
T0.Merge(i, i + 1), T1.Merge(n - i + 1, n - i + 2);
}
inline int Prev(int i)
{
return n - T1.gfa(n - i + 1) + 2;
}
inline int Next(int i)
{
return T0.gfa(i) - 1;
}
inline void Clear()
{
T0.Clear(), T1.Clear();
}
}T;
inline void Add(int a, int b)
{
ne[ ++ idx] = la[a];
la[a] = idx;
en[idx] = b;
}
inline void DFS1(int u, int f)
{
fa[u] = f, dep[u] = dep[f] + 1, siz[u] = 1;
for(int i = la[u]; i; i = ne[i])
{
int v = en[i];
if(v != f)
{
DFS1(v, u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}
}
inline void DFS2(int u, int f)
{
top[u] = f;
rnk[in[u] = ++ dfst] = u;
if(son[u])
{
DFS2(son[u], f);
for(int i = la[u]; i; i = ne[i])
{
int v = en[i];
if(v != son[u] && v != fa[u]) DFS2(v, v);
}
}
out[u] = dfst;
}
inline int LCA(int u, int v)
{
while(top[u] != top[v])
{
dep[top[u]] > dep[top[v]] ? (u = fa[top[u]]) : (v = fa[top[v]]);
}
return dep[u] < dep[v] ? u : v;
}
inline void DFS3(int u)
{
if(son[u])
{
for(int i = la[u]; i; i = ne[i])
{
int v = en[i];
if(v != fa[u] && v != son[u])
{
DFS3(v);
T.Clear();
}
}
DFS3(son[u]);
for(int i = out[son[u]] + 1; i <= out[u]; i ++ )
T.Insert(rnk[i]);
}
T.Insert(u);
for(int j : intv[u])
{
p[j].l = T.Prev(j);
p[j].r = T.Next(j);
p[j].d = p[j].r - p[j].l;
p[j].t = dep[u];
}
}
struct SGT{
int m, t[N * 4];
inline void Build(int n)
{
m = 1;
while(m < n + 2) m <<= 1;
for(int i = 1; i < m * 2; i ++ ) t[i] = 0;
}
inline void Insert(int i, int d)
{
for(i += m; i; i >>= 1) t[i] = max(t[i], d);
}
inline int Query(int x, int y)
{
int s = 0;
for(x += m - 1, y += m + 1; x ^ y ^ 1; x >>= 1, y >>= 1)
{
if(~x & 1) s = max(s, t[x ^ 1]);
if( y & 1) s = max(s, t[y ^ 1]);
}
return s;
}
}S;
struct ST{
int f[K][N];
inline void Init()
{
for(int i = 1; i <= n; i ++ ) f[0][i] = dep[i];
for(int i = 1; i < K; i ++ )
for(int j = 1; j <= n - (1 << i) + 1; j ++ )
f[i][j] = max(f[i - 1][j], f[i - 1][j + (1 << (i - 1))]);
}
inline int Query(int l, int r)
{
int k = __lg(r - l + 1);
return max(f[k][l], f[k][r - (1 << k) + 1]);
}
}S0;
int main()
{
freopen("query.in", "r", stdin);
freopen("query.out", "w", stdout);
Read(n);
for(int i = 1; i < n; i ++ )
{
int a, b;
Read(a), Read(b);
Add(a, b), Add(b, a);
}
DFS1(1, 0), DFS2(1, 1);
for(int i = 1; i < n; i ++ ) intv[LCA(i, i + 1)].push_back(i);
T.Init();
DFS3(1);
S0.Init();
Read(m);
for(int i = 1; i <= m; i ++ )
{
Read(q[i].l), Read(q[i].r), Read(q[i].d);
q[i].d -- , q[i].t = i;
ans[i] = 0;
if(!q[i].d) ans[i] = S0.Query(q[i].l, q[i].r);
}
S.Build(n);
sort(p + 1, p + n, [](const Point &x, const Point &y){return x.d > y.d;});
sort(q + 1, q + m + 1, [](const Point &x, const Point &y){return x.d > y.d;});
for(int i = 1, j = 1; i <= m; i ++ )
{
while(j < n && p[j].d >= q[i].d)
{
S.Insert(p[j].r, p[j].t);
j ++ ;
}
ans[q[i].t] = max(ans[q[i].t], S.Query(q[i].l + q[i].d, q[i].r));
}
S.Build(n);
sort(p + 1, p + n, [](const Point &x, const Point &y){return x.r > y.r;});
sort(q + 1, q + m + 1, [](const Point &x, const Point &y){return x.r > y.r;});
for(int i = 1, j = 1; i <= m; i ++ )
{
while(j < n && p[j].r >= q[i].r)
{
S.Insert(p[j].l, p[j].t);
j ++ ;
}
ans[q[i].t] = max(ans[q[i].t], S.Query(1, q[i].r - q[i].d));
}
for(int i = 1; i <= m; i ++ ) printf("%d\n", ans[i]);
return 0;
}