#include <bits/stdc++.h>
using namespace std;
const int mxN = 2e5 + 1000;
const int mxB = 20;
#define all(x) x.begin(), x.end()
#define int long long
vector<int> point[mxN];
vector<pair<int, int>> adj[mxN];
vector<pair<int, int>> edges, checkpoints;
vector<tuple<int, int, int, int, int, int>> Query;
vector<int> euler;
int tin[mxN], tout[mxN], st[mxN], en[mxN], stt[mxN], enn[mxN], depth[mxN], leader[mxN], ans[mxN], ok[mxN], tim = -1;
pair<int, int> dp[mxN * 4][mxB];
pair<long long, int> seg[mxN * 4];
pair<long long, int> combine(const pair<long long, int> &left, const pair<long long, int> &right){
return {left.first + right.first, left.second + right.second};
}
void update(int node, int start, int end, int idx, pair<long long, int> val){
if(start == end){
seg[node].first += val.first, seg[node].second += val.second;
return;
}
int mid = start + (end - start) / 2;
if(idx <= mid) update(node * 2 + 1, start, mid, idx, val);
else update(node * 2 + 2, mid + 1, end, idx, val);
seg[node] = combine(seg[node * 2 + 1], seg[node * 2 + 2]);
}
void update(int idx, pair<long long, int> val){
update(0, 0, tim, idx, val);
}
pair<long long, int> query(int node, int start, int end, int l, int r){
if(start > r || end < l) return {0, 0};
if(start >= l && end <= r) return seg[node];
int mid = start + (end - start) / 2;
return combine(query(node * 2 + 1, start, mid, l, r), query(node * 2 + 2, mid + 1, end, l, r));
}
void dfs(int u = 1, int par = 0){
tin[u] = ++tim, st[u] = (int) euler.size(), depth[u] = depth[par] + 1;
euler.push_back(u);
for(auto [v, id] : adj[u]){
if(v ^ par){
leader[id] = v;
dfs(v, u);
euler.push_back(u);
}
}
en[u] = (int) euler.size();
euler.push_back(u);
tout[u] = ++tim;
}
void build(){
int n = (int) euler.size();
for(int i = 0; i < n; ++i){
dp[i][0] = {depth[euler[i]], euler[i]};
}
for(int j = 1; j < mxB; ++j){
for(int i = 0; i + (1 << j) - 1 < n; ++i){
dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
}
}
int lca(int u, int v){
int l = en[u], r = en[v];
if(l > r) swap(l, r);
int k = __lg(r - l + 1);
return min(dp[l][k], dp[r - (1 << k) + 1][k]).second;
}
pair<long long, int> path_sum(int u, int v){
if(u == v) return {0ll, 0ll};
int lc = lca(u, v);
pair<long long, int> ulc = query(0, 0, tim, 0, tin[u]);
pair<long long, int> vlc = query(0, 0, tim, 0, tin[v]);
pair<long long, int> l_lc = query(0, 0, tim, 0, tin[lc]);
return {ulc.first + vlc.first - 2 * l_lc.first, ulc.second + vlc.second - 2 * l_lc.second};
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n, m, q;
cin >> n >> m >> q;
for(int i = 1; i <= n - 1; ++i){
int u, v;
cin >> u >> v;
adj[u].push_back({v, i});
adj[v].push_back({u, i});
}
dfs();
build();
for(int i = 1; i <= m; ++i){
int edge_id, silver;
cin >> edge_id >> silver;
checkpoints.push_back({silver, edge_id});
update(tin[leader[edge_id]], {0, 1});
update(tout[leader[edge_id]], {0, -1});
}
sort(all(checkpoints));
for(int i = 0; i < q; ++i) {
int u, v, gold;
long long silver;
cin >> u >> v >> gold >> silver;
pair<long long, int> x = path_sum(u, v);
Query.push_back({silver, gold, u, v, i, x.second});
stt[i] = 0, enn[i] = m - 1, ans[i] = -1;
point[(stt[i] + enn[i]) / 2].push_back(i);
if(x.second <= gold) ans[i] = gold - x.second;
}
for(auto [v, i] : checkpoints) {
update(tin[leader[i]], {0, -1});
update(tout[leader[i]], {0, 1});
}
for(int _ = 0; _ < mxB; ++_){
for(int i = 0; i < m; ++i){
auto [___, edge_id] = checkpoints[i];
update(tin[leader[edge_id]], {___, 1});
update(tout[leader[edge_id]], {-___, -1});
for(auto que : point[i]){
auto [silver, gold, u, v, id, total] = Query[que];
pair<long long, int> cur = path_sum(u, v);
if(cur.first <= silver){
ans[id] = max(ans[id], gold - total + cur.second);
stt[id] = i + 1;
}else{
enn[id] = i - 1;
}
}
point[i].clear();
}
for(int i = 0; i < q; ++i){
if(stt[i] <= enn[i]) point[(stt[i] + enn[i]) / 2].push_back(i);
}
for(int i = 0; i < m; ++i){
auto [___, edge_id] = checkpoints[i];
update(tin[leader[edge_id]], {-___, -1});
update(tout[leader[edge_id]], {___, 1});
}
}
for(int i = 0; i < q; ++i) cout << ans[i] << "\n";
return 0;
}