/**
* 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;
constexpr int maxn = 1e5 + 5, Log = 17;
int n, m, q, timer = 0, up[Log][maxn];
int h[maxn], st[maxn], en[maxn], lo[maxn], hi[maxn];
long long total_gold[maxn], res[maxn];
vector<int> tree[maxn];
struct metal
{
long long gold, silver;
} bit[maxn];
struct Edge
{
int u, v;
} e[maxn];
struct Checkpoints
{
int p;
long long c;
bool operator < (Checkpoints o) const {
return c < o.c;
}
} pts[maxn];
struct Query
{
int s, t;
long long x, y;
} qr[maxn];
metal operator + (metal a, metal b)
{
return {a.gold + b.gold, a.silver + b.silver};
}
metal operator - (metal a, metal b)
{
return {a.gold - b.gold, a.silver - b.silver};
}
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);
}
int GetBit(int x, int k)
{
return (x >> k) & 1;
}
void DFSVisit(int u, int p)
{
st[u] = ++timer, up[0][u] = p;
for (int i = 1; i < Log; ++i)
up[i][u] = up[i - 1][up[i - 1][u]];
for (int v : tree[u])
if (v != p)
h[v] = h[u] + 1, DFSVisit(v, u);
en[u] = timer;
}
int lca(int u, int v)
{
if (h[u] < h[v]) swap(u, v);
for (int i = Log - 1; i >= 0; --i)
if (GetBit(h[u] - h[v], i))
u = up[i][u];
if (u == v) return u;
for (int i = Log - 1; i >= 0; --i)
if (up[i][u] != up[i][v])
u = up[i][u], v = up[i][v];
return up[0][u];
}
metal query(int u, int v)
{
int k = lca(u, v);
return get(st[u]) + get(st[v]) - (get(st[k]) + get(st[k]));
}
void UpdateEdge(int i, long long x, long long y)
{
int u = e[i].u, v = e[i].v;
if (h[u] < h[v]) swap(u, v);
update(st[u], +x, +y), update(en[u] + 1, -x, -y);
}
void ReadData()
{
cin >> n >> m >> q;
for (int i = 1; i < n; ++i)
{
int u, v;
cin >> u >> v;
tree[u].push_back(v);
tree[v].push_back(u);
e[i] = {u, v};
}
DFSVisit(1, 0);
for (int i = 1; i <= m; ++i)
{
cin >> pts[i].p >> pts[i].c;
UpdateEdge(pts[i].p, 1, 0);
}
for (int i = 1; i <= q; ++i)
{
int s, t;
long long x, 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;
}
}
void solvebytrvietbels()
{
ReadData();
sort(pts + 1, pts + 1 + m);
vector<int> Q = {-1};
while (!Q.empty())
{
Q.clear();
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);
Q.push_back(i);
}
for (int i = 1; i <= m; ++i)
{
UpdateEdge(pts[i].p, 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.gold, 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;
}