/**
* Author: trviet
* Studies at: Le Hong Phong High School for the Gifted
**/
#include <bits/stdc++.h>
#define ____vuviet__ signed main
#define taskname "trvietbels"
using namespace std;
using metal = pair<long long, long long>;
#define gold first
#define silver second
constexpr int maxn = 1e5 + 5;
int n, m, q, timer = 0, lo[maxn], hi[maxn];
int par[maxn], head[maxn], id[2][maxn], sz[maxn];
long long total_gold[maxn], res[maxn];
metal bit[maxn];
// id(0) = edge -> v, id(1) = hld id
metal operator + (metal a, metal b)
{
metal res;
res.gold = a.gold + b.gold;
res.silver = a.silver + b.silver;
return res;
}
metal operator - (metal a, metal b)
{
metal res;
res.gold = a.gold - b.gold;
res.silver = a.silver - b.silver;
return res;
}
void update(int i, long long x, long long y)
{
metal New = {x, y};
for (; i <= n; i += i & -i)
bit[i] = bit[i] + New;
}
metal get(int i)
{
metal res = {0, 0};
for (; i > 0; i -= i & -i)
res = res + bit[i];
return res;
}
metal cost(int l, int r)
{
return get(r) - get(l - 1);
}
metal query(int u, int v)
{
metal res = {0, 0};
while (head[u] != head[v])
{
if (sz[head[u]] > sz[head[v]]) swap(u, v);
res = res + cost(id[1][head[u]], id[1][u]);
u = par[head[u]];
}
if (sz[u] > sz[v]) swap(u, v);
res = res + cost(id[1][v] + 1, id[1][u]);
return res;
}
struct Checkpoint
{
int u;
long long c;
bool operator < (Checkpoint o) const {
return c < o.c;
}
} pts[maxn];
struct Edge
{
int vertex, id;
};
struct Query
{
int s, t, x;
long long y;
} qr[maxn];
vector<Edge> tree[maxn];
void DFSVisit(int u, int p)
{
par[u] = p, sz[u] = 1;
for (Edge child : tree[u])
{
int v = child.vertex, i = child.id;
if (v != p) {
DFSVisit(v, u), sz[u] += sz[v], id[0][i] = v;
}
}
}
void Heavy(int u, int h, int p)
{
head[u] = h, id[1][u] = ++timer;
if (tree[u].empty()) return;
int x = -1;
for (Edge child : tree[u])
{
int v = child.vertex;
if (v != p && (x == -1 || sz[v] > sz[x]))
x = v;
}
if (x != -1) Heavy(x, h, u);
for (Edge child : tree[u])
{
int v = child.vertex;
if (v != p && v != x)
Heavy(v, v, u);
}
}
void solvebytrvietbels()
{
cin >> n >> m >> q;
for (int i = 2; i <= n; ++i)
{
int u, v;
cin >> u >> v;
tree[u].push_back({v, i - 1});
tree[v].push_back({u, i - 1});
}
DFSVisit(1, 0);
Heavy(1, 1, 0);
for (int i = 1; i <= m; ++i)
{
int p;
long long c;
cin >> p >> c;
pts[i] = {id[0][p], c};
}
sort(pts + 1, pts + 1 + m);
for (int i = 1; i <= m; ++i)
update(id[1][pts[i].u], 1, 0);
for (int i = 1; i <= q; ++i)
{
int s, t, x;
long long y;
cin >> s >> t >> x >> y;
qr[i] = {s, t, x, y};
total_gold[i] = query(s, t).gold;
lo[i] = 1, hi[i] = m;
}
int Log2 = __lg(m + 5);
for (int t = 0; t < Log2 + 1; ++t)
{
for (int i = 1; i <= n; ++i)
bit[i] = {0, 0};
vector<vector<int>> queries(m + 5);
for (int i = 1; i <= q; ++i)
if (lo[i] <= hi[i])
queries[(lo[i] + hi[i]) / 2].push_back(i);
for (int i = 1; i <= m; ++i)
{
update(id[1][pts[i].u], 1, pts[i].c);
for (int id : queries[i])
{
metal cur = query(qr[id].s, qr[id].t);
if (cur.silver <= qr[id].y) {
res[id] = cur.first, lo[id] = i + 1;
} else {
hi[id] = i - 1;
}
}
}
}
for (int i = 1; i <= q; ++i)
{
long long need = total_gold[i] - res[i];
cout << (need > qr[i].x ? -1 : qr[i].x - need) << "\n";
}
}
void freopen_stdio(string speech)
{
cin.tie(0)->sync_with_stdio(0);
cerr << speech << "\n";
if (fopen(taskname ".inp", "r"))
{
freopen(taskname ".inp", "r", stdin);
freopen(taskname ".out", "w", stdout);
}
}
____vuviet__()
{
freopen_stdio("...miss you...");
int t = 1;
// cin >> t;
while (t-- > 0)
solvebytrvietbels();
return 0;
}