#include <algorithm>
#include <array>
#include <cassert>
#include <cctype>
#include <cstdio>
#include <map>
#include <set>
#include <sys/types.h>
#include <tuple>
#include <vector>

#define let const auto
#define mut auto

template<typename T>
using vec = std::vector<T>;
using ull = unsigned long long;
using ll = long long;

using std::tuple, std::array;

template<typename T>
T read() {
	T s = 0, w = 1, c = getchar();
	while (!isdigit(c)) {
		if (c == '-') {
			w = -1;
		}
		c = getchar();
	}
	while (isdigit(c)) {
		s = s * 10 + c - '0';
		c = getchar();
	}
	return s * w;
}

using Query = tuple<uint, uint, uint>;
using Edge = tuple<uint, uint>;

class Config {
public:
	uint n, q;
	vec<Edge> edges;
	vec<Query> queries;
};

vec<uint> solve(const Config &);

int main() {
	freopen("query.in", "r", stdin);
	freopen("query.out", "w", stdout);

	let n = read<uint>();
	mut config = Config{n, 0, vec<Edge>(n - 1)};
	for (mut &[u, v] : config.edges) {
		u = read<uint>(), v = read<uint>();
	}
	config.q = read<uint>();
	config.queries = vec<Query>(config.q);
	for (mut &[l, r, k] : config.queries) {
		l = read<uint>(), r = read<uint>(), k = read<uint>();
	}
	let ans = solve(config);
	for (let i : ans) {
		printf("%u\n", i);
	}

	fclose(stdin);
	fclose(stdout);
	return 0;
}

class Graph {
	class Edge {
	public:
		uint v;
		Edge *nxt;
	};

	vec<Edge*> head;
public:
	Graph(uint n) : head(n, nullptr) {}

	void add_edge(uint u, uint v) {
		head[u] = new Edge{v, head[u]};
		head[v] = new Edge{u, head[v]};
	}

	Edge* begin(uint u) {
		return head[u];
	}
};

class Lca {
	Graph &graph;
	uint n;
	vec<uint> dep;
	vec<array<uint, 22>> fa;

	void dfs(uint u) {
		for (mut i = graph.begin(u); i; i = i->nxt) {
			if(i->v != fa[u][0]) {
				fa[i->v][0] = u;
				dep[i->v] = dep[u] + 1;
				dfs(i->v);
			}
		}
	}

public:
	Lca(uint n, Graph &graph) : graph(graph), n(n), dep(n), fa(n) {
		dfs(0);

		for (uint i = 1; i < 22; i++) {
			for (uint j = 0; j < n; j++) {
				fa[j][i] = fa[fa[j][i - 1]][i - 1];
			}
		}
	}

	uint get(uint a, uint b) const {
		if (dep[a] < dep[b]) {
			std::swap(a, b);
		}
		for (uint i = 21; i != -1; i--) {
			if (dep[fa[a][i]] >= dep[b]) {
				a = fa[a][i];
			}
		}
		if (a == b) {
			return a;
		}
		for (uint i = 21; i != -1; i--) {
			if (fa[a][i] != fa[b][i]) {
				a = fa[a][i];
				b = fa[b][i];
			}
		}
		return fa[a][0];
	}

	uint get_dep(uint u) {
		return dep[u];
	}
};

class SegTree {
	class Node {
	public:
		uint l, r;
		Node *ls, *rs;
		uint val;
	};

	Lca &lca;

	Node *rt;

	void build(Node *u, uint l, uint r) {
		u->l = l, u->r = r;
		if (l == r) {
			u->val = l;
			return ;
		}
		let mid = (l + r) >> 1;
		u->ls = new Node{}, u->rs = new Node{};
		build(u->ls, l, mid);
		build(u->rs, mid + 1, r);
		u->val = lca.get(u->ls->val, u->rs->val);
	}

	uint query(Node *u, uint l, uint r) {
		if (l <= u->l && u->r <= r) {
			return u->val;
		}
		uint mid = (l + r) >> 1;
		if (l <= mid) {
			uint val = query(u->ls, l, r);
			if (r > mid) {
				return lca.get(val, query(u->rs, l, r));
			}else{
				return val;
			}
		} else {
			return query(u->rs, l, r);
		}
	}

public:
	SegTree(uint n, Lca &lca) : lca(lca) {
		rt = new Node;
		build(rt, 0, n - 1);
	}

	uint query(uint l, uint r) {
		return query(rt, l, r);
	}
};

vec<uint> solve(const Config &config) {
	Graph graph(config.n);
	for (let &[u, v] : config.edges) {
		graph.add_edge(u - 1, v - 1);
	}	
	Lca lca(config.n, graph);
	SegTree tree(config.n, lca);

	mut ans = vec<uint>();
	for (let &[l, r, k] : config.queries) {
		mut dep = 0u;
		for (uint i = l - 1; i + k - 1 < r; i++) {
			dep = std::max(dep, lca.get_dep(tree.query(i, i + k - 1)));
		}
		ans.push_back(dep + 1);
	}

	return ans;
}