#include <cstdio>
#include <vector>
#include <array>
#include <algorithm>

namespace Main {

using namespace std;

typedef long long LL;

LL read() {
	LL res, f = 1, c;
	for (c = getchar(); (c < '0' || c > '9') && c != '-';)
		c = getchar();
	if (c == '-') {
		f = -1;
		c = getchar();
	}
	for (res = 0; '0' <= c && c <= '9'; c = getchar())
		res = res * 10 + (c & 15);
	return res * f;
}

constexpr bool T = 0;
constexpr int N = 500005, LG = 19, B = 5000;

/*
struct SparseTable {
	static constexpr int N = 500005;
	int f[N][
	*/
array<int, 4> operator+(const array<int, 4> &x, const array<int, 4> &y) {
	array<int, 4> res;
	res[0] = max(max(x[0], y[0]), x[3] + y[2]);
	res[1] = x[1] + y[1];
	res[2] = x[2] + (x[2] == x[1] ? y[2] : 0);
	res[3] = y[3] + (y[3] == y[1] ? x[3] : 0);
	return res;
}

struct SegTree {
	static constexpr int N = 20000005;
	static int n;
	array<int, 4> s[N];
	int lc[N], rc[N], tot;

	void clear(int n) {
		this->n = n;
		tot = 0;
		return;
	}

	int cp(int k) {
//		printf("%d\n", tot);
		s[++tot] = s[k];
		lc[tot] = lc[k];
		rc[tot] = rc[k];
		return tot;
	}

	void update(int k, int l, int r) {
		s[k] = s[lc[k]] + s[rc[k]];
		s[k][1] = r - l + 1;
		return;
	}

	int merge(int x, int y, int l = 1, int r = n) {
		if (!x || !y)
			return x | y;
		int mid = (l + r) >> 1, k = ++tot;
		lc[k] = merge(lc[x], lc[y], l, mid);
		rc[k] = merge(rc[x], rc[y], mid + 1, r);
		update(k, l, r);
		return k;
	}

	void modify(int x, int &k, int l = 1, int r = n) {
//		printf("%d %d %d %d\n", x, k, l, r);
		k = cp(k);
		if (l == r) {
			s[k] = {1, 1, 1, 1};
			return;
		}
		int mid = (l + r) >> 1;
		x <= mid ? modify(x, lc[k], l, mid) : modify(x, rc[k], mid + 1, r);
		update(k, l, r);
		return;
	}

	array<int, 4> query(int x, int y, int k, int l = 1, int r = n) {
		if (y < l || r < x || !k)
			return {0, 0, 0, 0};
		if (x <= l && r <= y)
			return s[k];
		int mid = (l + r) >> 1;
		if (x <= mid && mid < y)
			return query(x, y, lc[k], l, mid) + query(x, y, rc[k], mid + 1, r);
		return x <= mid ? query(x, y, lc[k], l, mid) : query(x, y, rc[k], mid + 1, r);
	}
};

int SegTree::n;

SegTree tr;
int dep[N], f[N][LG], rt[N], p[N];
vector<int> e[N];

namespace Bf {

constexpr int N = 5005;
int dep[N], dfn[N], res[N][N];

struct SparseTable {
	static constexpr int N = 5005, LG = 13;
	int lg[N], f[LG][N];

	int cmp(int x, int y) {
		return dep[x] < dep[y] ? x : y;
	}

	void build(int n) {
		lg[0] = -1;
		for (int i = 1; i <= n; ++i)
			lg[i] = lg[i >> 1] + 1;
		for (int k = 0; k < LG - 1; ++k)
			for (int i = 1; i + (2 << k) <= n + 1; ++i)
				f[k + 1][i] = cmp(f[k][i], f[k][i + (1 << k)]);
		return;
	}

	int query(int l, int r) {
		int k = lg[r - l + 1];
		return cmp(f[k][l], f[k][r + 1 - (1 << k)]); 
	}
} st;

int lca(int x, int y) {
	if (x == y)
		return x;
	if (dfn[x] > dfn[y])
		swap(x, y);
	return st.query(dfn[x], dfn[y] - 1);
}

void dfs(int x, int fa) {
	dep[x] = dep[fa] + 1;
	st.f[0][dfn[x] = ++dfn[0]] = x;
	for (int i : e[x])
		if (i != fa) {
			dfs(i, x);
			st.f[0][dfn[0]] = x;
		}
	return;
}

void sol(int n, int q) {
//	puts("fjdkls");
	dfs(1, 0);
	st.build(n - 1);
//	printf("%d\n", lca(4, 5));
	for (int i = 1; i <= n; ++i) {
		int lc = i;
		res[1][i] = dep[i];
		for (int j = i + 1; j <= n; ++j)
			res[j - i + 1][i] = dep[lc = lca(lc, j)];
	}
	for (int i = 1; i <= q; ++i) {
		int l = read(), r = read(), k = read(), ans = 1;
		for (int j = l; j + k - 1 <= r; ++j)
			ans = max(ans, res[k][j]);
		printf("%d\n", ans);
	}
	return;
}
}

void dfs(int x, int fa) {
	tr.modify(x, rt[x]);
	dep[x] = dep[f[x][0] = fa] + 1;
	p[dep[x]] = x;
	for (int i = 0; i < LG - 1; ++i)
		f[x][i + 1] = f[f[x][i]][i];
	for (int i : e[x])
		if (i != fa) {
			dfs(i, x);
			rt[x] = tr.merge(rt[x], rt[i]);
		}
	return;
}

bool check(int x, int l, int r, int k) {
	return x <= 1 || tr.query(l, r, rt[x])[0] >= k;
}

int cal(int x, int l, int r, int k, int res) {
	int i = 0; 
	res = -1;
//	printf("%d %d %d %d\n", l, r, k, x);
	if (check(x, l, r, k))
		return dep[x];
//	for (; !check(f[x][i], l, r, k) && dep[x] > res + 1; ++i)
//		x = f[x][i];
//	for (int i = LG - 1; ~i && dep[x] > res + 1; --i)
//		if (!check(f[x][i], l, r, k))
//			x = f[x][i];
//	printf("%d %d %d %d\n", l, r, k, x);
	return 0;
	return dep[x] - 1;
}

int query(int l, int r, int k, int n) {
	int ans = 1;
//	printf("## %d %d %d\n", l, r, k);
	for (int i = 1; i <= n; i ++)
//	for (int i = l + k - 1; i <= r; i += k)
		ans = max(ans, cal(i, l, r, k, ans));
	return ans;
}

int queryA(int l, int r, int k, int n) {
	int i = 1, s = 0;
	for (; s + i <= n && tr.query(l, r, rt[p[s + i]])[0] >= k; i <<= 1)
		s += i;
	for (i >>= 1; i; i >>= 1)
		if (s + i <= n && tr.query(l, r, rt[p[s + i]])[0] >= k)
			s += i;
	return s;
}

void solve() {
//	printf("%d\n", sizeof(Bf::res) / 1024);
	int n = read();
	for (int i = 1; i < n; ++i) {
		int u = read(), v = read();
		e[u].emplace_back(v);
		e[v].emplace_back(u);
	}
	int q = read();
	if (n <= B && q <= B) {
		Bf::sol(n, q);
		return;
	}
	tr.clear(n);
	dfs(1, 1);
//	printf("%d\n", tr.tot);
//	printf("%d\n", sizeof(tr) / 1024);
//	return;
//	printf(" %d\n", tr.query(2, 5, rt[3])[0]);
	for (int i = 1; i <= q; ++i) {
//		printf("#%d\n", i);
		int l = read(), r = read(), k = read();
//		printf("%d\n", k == r - l + 1 || 1 ? query(l, r, k, n) : queryA(l, r, k, n));
//		printf("%d\n", tr.query(l, r, rt[p[4]])[0]);
		printf("%d\n", queryA(l, r, k, n));
//		if (k < B) {
//			printf("%d\n", st[k].query(l, r - k + 1));
//		} else
//			printf("%d\n", query(l, r, k));
	}
	return;
}

void main() {
	freopen("query.in", "r", stdin);
	freopen("query.out", "w", stdout);
	for (int t = T ? read() : 1; t; --t)
		solve();
	return;
}
}

int main() {
	Main::main();
	return 0;
}

