#include <bits/stdc++.h>
using namespace std;
#define pb push_back
const int MaxN = 2e5+7;
const int MaxM = 25e3+7;
const int S = 450;
int Tin[MaxN],Tout[MaxN],col[MaxN],n,m,q,cnt_Heavy,cnt_par[MaxN],cnt_child[MaxN][S],ID[MaxN];
int f[MaxM][S],g[MaxM][S];
vector<int> adj[MaxN],lis[MaxM];
struct FenwickTree {
int n;
vector<int> fw;
void Set(int _n){
n = _n;
fw.assign(n + 7,0);
}
void Upd(int u,int v) {
for (;u <= n; u += u&-u) {
fw[u] += v;
}
}
int Get(int u) {
int res = 0;
for (;u;u-=u&-u) {
res += fw[u];
}
return res;
}
int Get(int l,int r) {
return Get(r) - Get(l-1);
}
} fw;
void dfs(int u) {
Tin[u] = ++Tin[0];
for (int j=1;j<=m;j++) g[col[u]][j] += cnt_par[j];
cnt_par[col[u]]++;
cnt_child[u][col[u]]++;
for (int v : adj[u]) {
dfs(v);
for (int j=1;j<=m;j++) {
cnt_child[u][j] += cnt_child[v][j];
f[col[u]][j] += cnt_child[v][j];
}
}
cnt_par[col[u]]--;
Tout[u] = Tin[0];
}
void Query() {
int r1, r2; cin >> r1 >> r2;
if (ID[r2]) {
cout << f[r1][r2] << endl;
return;
}
if (ID[r1]) {
cout << g[r2][r1] << endl;
return;
}
int res = 0;
for (int x : lis[r2]) fw.Upd(Tin[x],1);
for (int x : lis[r1]) res += fw.Get(Tin[x],Tout[x]);
for (int x : lis[r2]) fw.Upd(Tin[x],-1);
cout << res << endl;
return;
}
int main() {
cin >> n >> m >> q;
cin >> col[1];
lis[col[1]].pb(1);
for (int i=2;i<=n;i++) {
int p;
cin >> p;
cin >> col[i];
adj[p].pb(i);
lis[col[i]].pb(i);
}
cnt_Heavy = 0;
for (int i=1;i<=m;i++) {
if (lis[i].size() > S) {
ID[i] = ++cnt_Heavy;
}
}
dfs(1);
fw.Set(n);
while (q--) Query();
}