#include <bits/stdc++.h>
using namespace std;
mt19937 timmy_loves_gambling(73);
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define readv(v) do { for(auto &i: v) cin >> i; } while(0)
#define _ << " " <<
#define lf "\n"
#define ll long long
#define ull unsigned long long
#define pii pair<int, int>
#define pll pair<long long, long long>
#define fi first
#define se second
template<typename... Args>
using vec = vector<Args...>;
#ifndef MARCO
bool dbg = 0;
#define infor(str, ...)
#define infof(str, ...)
#else
bool dbg = 1;
#define infor(str, ...) do { print(stderr, str, ##__VA_ARGS__); } while(0)
#define infof(str, ...) do { println(stderr, str, ##__VA_ARGS__); } while(0)
#endif
constexpr int LOG = 20;
int N, M, Q;
vec<int> tin, tout, depth;
vec<vec<int>> tb;
vector<vec<int>> G;
vec<int> par;
vec<pii> ed;
int highest(int a, int b) {
if(depth[a] < depth[b]) return a;
return b;
}
void dfs(int v, int p, int d) {
par[v] = p;
depth[v] = d;
static int t = 0;
tb[0][t] = v;
tin[v] = t++;
for(auto &u: G[v]) {
if(u == p) continue;
dfs(u, v, d+1);
tb[0][t++] = v;
}
tout[v] = t;
}
void construct() {
for(int i=1; i<LOG; i++) {
int pw = (1 << i);
for(int l=0; l+pw <= 2*N; l++)
tb[i][l] = highest(tb[i-1][l], tb[i-1][l + pw/2]);
}
}
int get_lca(int l, int r) {
l = tin[l], r = tin[r];
if(l > r) swap(l, r);
r++;
int s = 31 - __builtin_clz(r - l);
int pw = (1 << s);
return highest(tb[s][l], tb[s][r-pw]);
}
struct segtree {
vector<ll> t, lazy;
segtree() {
t.resize(N*8);
lazy.resize(N*8);
}
void push(int v) {
for(int u = v*2; u < v*2+2; u++) {
t[u] += lazy[v];
lazy[u] += lazy[v];
}
lazy[v] = 0;
}
void add(int v, int l, int r, int ql, ll qr, ll x) {
if(qr <= l || r <= ql) return;
if(ql <= l && r <= qr) {
t[v] += x;
lazy[v] += x;
return;
}
push(v);
int m = (l+r)/2;
add(v*2, l, m, ql, qr, x);
add(v*2+1, m, r, ql, qr, x);
}
void add(int v, ll x) {
add(1, 0, N*2, tin[v], tout[v], x);
}
ll get(int v, int l, int r, int q) {
if(r-l == 1) return t[v];
push(v);
int m = (l+r)/2;
if(q < m) return get(v*2, l, m, q);
return get(v*2+1, m, r, q);
}
ll get(int v) {
return get(1, 0, N*2, tin[v]);
}
ll query(int a, int b, int lca) {
return get(a) + get(b) - 2*get(lca);
}
};
signed main(){
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> N >> M >> Q;
G.resize(N);
tin.resize(N);
tout.resize(N);
depth.resize(N);
ed.resize(N-1);
par.resize(N);
tb = vector(LOG, vector<int>(2*N));
for(int i=0; i<N-1; i++) {
int a, b; cin >> a >> b;
a--, b--;
G[a].push_back(b);
G[b].push_back(a);
ed[i] = {a, b};
}
dfs(0, -1, 0);
construct();
segtree silver, gold;
vec<pll> cost(M); // [silver coins, node]
for(int i=0; i<M; i++) {
int e, c; cin >> e >> c;
e--;
auto [a, b] = ed[e];
if(par[b] == a) swap(a, b);
cost[i] = {c, a};
gold.add(a, 1);
}
sort(all(cost));
vec<pii> Qs(Q);
vec<ll> Qgold(Q), Qsilver(Q);
vec<ll> ans(Q); // minimum gold needed
for(int i=0; i<Q; i++) {
cin >> Qs[i].fi >> Qs[i].se >> Qgold[i] >> Qsilver[i];
Qs[i].fi--, Qs[i].se--;
ans[i] = gold.query(Qs[i].fi, Qs[i].se, get_lca(Qs[i].fi, Qs[i].se));
}
int s = 0;
auto conquer = [&](int l, int r, vector<int> &id, auto &&conquer) -> void {
if(id.empty()) return;
int m = (l+r)/2;
infof("conquering l = {} r = {} m = {}", l, r, m);
while(s < m) {
silver.add(cost[s].se, cost[s].fi);
gold.add(cost[s].se, -1);
s++;
}
while(s > m) {
s--;
silver.add(cost[s].se, -cost[s].fi);
gold.add(cost[s].se, +1);
}
vec<int> L, R;
for(auto &i: id) {
auto &[a, b] = Qs[i];
int lca = get_lca(a, b);
ll ks = silver.query(a, b, lca);
ll kg = gold.query(a, b, lca);
if(ks <= Qsilver[i]) {
ans[i] = min(ans[i], kg);
R.push_back(i);
}
else {
L.push_back(i);
}
}
if(r-l == 1) return;
conquer(l, m, L, conquer);
conquer(m, r, R, conquer);
};
vec<int> id(Q);
iota(all(id), 0);
conquer(0, M+1, id, conquer);
for(int i = 0; i < Q; i++) {
cout << max(-1LL, Qgold[i] - ans[i]) << lf;
}
}