// Starcraft 2 enjoyer //
#include <bits/stdc++.h>
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
using namespace std;
#define LSOne(X) ((X) & -(X))
const int N = 1e5 + 5;
const int M = 1 << 15;
const int B = 18;
const long long K = 2;
const int LG = 20;
const int INF = 2e9 + 5;
const int P = 31;
const int MOD = 1e9 + 7;
const int nx[] = {0, 1, 0, -1}, ny[] = {-1, 0, 1, 0};
struct Fenwick
{
vector<int> ft;
int n;
Fenwick(int len)
{
n = len;
ft.assign(n + 1, 0);
}
void update(int pos, int val)
{
while (pos <= n)
{
ft[pos] += val;
pos += LSOne(pos);
}
}
int get(int pos)
{
int sum = 0;
while (pos > 0)
{
sum += ft[pos];
pos -= LSOne(pos);
}
return sum;
}
int get(int l, int r)
{
return get(r) - get(l - 1);
}
};
int n, m, q, top[N], par[N], in[N], cid, bigchild[N], val[N], l[N], r[N], ans[N], num[N];
vector<int> adj[N];
vector<pair<int, int>> edge;
vector<array<int, 3>> edges;
array<int, 4> query[N];
vector<int> update[N];
int dfs1(int c, int p)
{
par[c] = p;
int j = -1;
int sz = 0;
bigchild[c] = -1;
for (int i : adj[c])
{
if (i == p)
continue;
int s = dfs1(i, c);
if (s > j)
{
j = s;
bigchild[c] = i;
}
sz += s;
}
sz++;
return sz;
}
void dfs2(int c, int p)
{
top[c] = p;
in[c] = cid++;
if (bigchild[c] == -1)
return;
dfs2(bigchild[c], p);
for (int i : adj[c])
{
if (i == par[c] || i == bigchild[c])
continue;
dfs2(i, i);
}
}
bool cmp(array<int, 3> &a, array<int, 3> &b)
{
return a[2] < b[2];
}
inline void solve()
{
cin >> n >> m >> q;
edges.push_back({n, n, -INF});
for (int x = 1; x <= n - 1; x++)
{
int a, b;
cin >> a >> b;
adj[a].push_back(b);
adj[b].push_back(a);
edge.push_back({a, b});
}
for (int x = 0; x < m; x++)
{
int i, w;
cin >> i >> w;
auto &[a, b] = edge[i - 1];
edges.push_back({a, b, w});
// cout << a << " " << b << " " << w << "\n";
}
cid = 1;
dfs1(1, 0);
dfs2(1, 1);
sort(edges.begin(), edges.end(), cmp);
for (int x = 0; x < q; x++)
{
int s, t, a, b;
cin >> s >> t >> a >> b;
query[x] = {s, t, a, b};
l[x] = 0, r[x] = m, ans[x] = 0;
}
for (int x = 0; x < LG; x++)
{
Fenwick ft1(n + 1), ft2(n + 1);
for (int y = 1; y <= m; y++)
{
update[y].clear();
auto &[a, b, w] = edges[y];
if (par[b] == a)
swap(a, b);
ft2.update(in[a], 1);
}
for (int y = 0; y < q; y++)
{
if (l[y] > r[y])
continue;
int m = (l[y] + r[y]) / 2;
update[m].push_back(y);
}
for (int y = 0; y <= m; y++)
{
auto &[a, b, w] = edges[y];
if (par[b] == a)
swap(a, b);
if (y > 0)
{
ft1.update(in[a], w);
ft2.update(in[a], -1);
}
for (int i : update[y])
{
auto [a, b, g, s] = query[i];
int sum = 0, cnt = 0;
for (; top[a] != top[b]; a = par[top[a]])
{
if (in[top[a]] < in[top[b]])
{
swap(a, b);
}
sum += ft1.get(in[top[a]], in[a]);
cnt += ft2.get(in[top[a]], in[a]);
}
if (in[a] > in[b])
swap(a, b);
sum += ft1.get(in[a], in[b]);
sum -= ft1.get(in[a], in[a]);
cnt += ft2.get(in[a], in[b]);
cnt -= ft2.get(in[a], in[a]);
if (sum <= s)
{
ans[i] = y;
num[i] = cnt;
l[i] = y + 1;
}
else
{
r[i] = y - 1;
}
}
}
}
for (int x = 0; x < q; x++)
{
auto &[a, b, g, s] = query[x];
if (num[x] > g)
{
cout << -1 << "\n";
}
else
{
cout << g - num[x] << "\n";
}
}
}
signed main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t = 1;
// cin >> t;
for (int x = 1; x <= t; x++)
{
solve();
}
return 0;
}