#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ll int
typedef pair<int,int> pi;
typedef vector <int> vi;
typedef vector <pi> vpi;
typedef pair<pi, ll> pii;
typedef set <ll> si;
typedef long double ld;
#define f first
#define s second
#define mp make_pair
#define FOR(i,s,e) for(int i=s;i<=int(e);++i)
#define DEC(i,s,e) for(int i=s;i>=int(e);--i)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
#define aFOR(i,x) for (auto i: x)
#define mem(x,i) memset(x,i,sizeof x)
#define fast ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define INF (ll)1e9
#define MOD 1000000007
typedef pair <vi, int> pvi;
typedef pair <int,pi> ipi;
typedef vector <pii> vpii;
typedef pair <pi,pi> pipi;
#define maxn 100010
int N,M,Q;
int st[maxn], en[maxn], depth[maxn],ckpt_depth[maxn];
vi adj[maxn];
int twok[maxn][20];
int co = 1;
void dfs(int x,int p){
	twok[x][0] = p;
	st[x] = co++;
	FOR(k,1,19){
		if (twok[x][k-1] == -1) twok[x][k] = -1;
		else twok[x][k] = twok[twok[x][k-1]][k-1];
	}
	aFOR(i,adj[x]) if (i != p){
		depth[i] = depth[x] + 1;
		dfs(i,x);
	}
	en[x] = co-1;
}
void dfs2(int x,int p){
	aFOR(i,adj[x]) if (i != p){
		ckpt_depth[i] += ckpt_depth[x];
		dfs2(i,x);
	}
}
int lca(int x,int y){
	if (depth[x] < depth[y]) swap(x,y);
	int d = depth[x] - depth[y];
	FOR(k,0,19) if ((1 << k) & d) x = twok[x][k];
	if (x == y) return x;
	DEC(k,19,0) if (twok[x][k] != twok[y][k]){
		x = twok[x][k]; y = twok[y][k];
	}
	return twok[x][0];
}
struct node{
	int s,e,m,val=0,lazy=0,num=0,lazynum=0;
	node *l,*r;
	
	node(int ss,int ee,bool create){
		s = ss; e = ee; m = (s + e) / 2;
		if (s != e && create){
			l = new node(s,m,create); r = new node(m+1,e,create);
		}
	}
	node* copy(){
		node* res = new node(s,e,0);
		res->val = val; res->lazy = lazy;
		res->l = l; res->r = r;
		res->num = num; res->lazynum = lazynum;
		return res;
	} 
	void prop(){
		if ((lazy == 0 && lazynum == 0) || s == e) return;
		l = l->copy(); r = r->copy();
		l->val += lazy; r->val += lazy;
		l->lazy += lazy; r->lazy += lazy;
		l->num += lazynum; r->num += lazynum;
		l->lazynum += lazynum; r->lazynum += lazynum;
		lazy = 0; lazynum = 0;
	}
		
	node* upd(int a,int b,int c){
		prop();
		//~ cout << a << ' ' << b << '\n';
		
		if (a > e || s > b) return this;
		if (a <= s && e <= b){
			node* res = copy();
			res->val += c; res->lazy += c;
			res->num++; res->lazynum++;
			return res;
		}
		node* res = copy();
		
		res->l = l->upd(a,b,c);
		res->r = r->upd(a,b,c);
		return res;
	}
	pi qry(int x){
		prop();
		if (s == e) return pi(val, num);
		else if (x > m) return r->qry(x);
		else return l->qry(x);
	}
}*root[maxn];
int32_t main(){
	fast;
	cin >> N >> M >> Q;
	vpi edges;
	int a,b;
	FOR(i,1,N-1){
		cin >> a >> b;
		adj[a].pb(b); adj[b].pb(a);
		edges.pb(pi(a,b));
	}
	vpi ckpt;
	int p,c;
	FOR(i,1,M){
		cin >> p >> c;
		ckpt.pb(pi(c,p));
	}
	root[0] = new node(1,N,1);
	dfs(1,-1);
	
	FOR(i,1,N) ckpt_depth[i] = 0;
	sort(all(ckpt));
	FOR(i,1,M){
		int p = ckpt[i-1].s, c = ckpt[i-1].f;
		int a = edges[p-1].f, b = edges[p-1].s;
		if (depth[a] < depth[b]) swap(a,b);
		ckpt_depth[a]++;
		root[i] = root[i-1]->upd(st[a], en[a], c);
	}
	dfs2(1,-1);
	int s,t,x,y;
	FOR(i,1,Q){
		cin >> s >> t >> x >> y;
		int u = lca(s,t);
		int l = 0, r = M+1;
		while (l + 1 < r){
			int m = (l + r) / 2;
			int w = root[m]->qry(st[s]).f + root[m]->qry(st[t]).f - 2*root[m]->qry(st[u]).f;
			if (w <= y){
				l = m;
			}else r = m;
		}
		int numsilver = root[l]->qry(st[s]).s + root[l]->qry(st[t]).s - 2*root[l]->qry(st[u]).s;
		int numgold = ckpt_depth[s] + ckpt_depth[t] - 2*ckpt_depth[u] - numsilver;
		//~ cout << ckpt_depth[s] << ' ' << ckpt_depth[t] << ' ' << ckpt_depth[u] << ' ' << numsilver << ' ' << ;
		cout << max(x - numgold, -1) << '\n';
	}
}
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |