```go
package main
import (
"bufio"
"io"
"os"
"strconv"
)
func main() {
data, _ := io.ReadAll(os.Stdin)
p := 0
nextInt := func() int {
for p < len(data) && (data[p] < '0' || data[p] > '9') {
p++
}
v := 0
for p < len(data) && data[p] >= '0' && data[p] <= '9' {
v = v*10 + int(data[p]-'0')
p++
}
return v
}
n := nextInt()
m := nextInt()
k := nextInt()
q := nextInt()
parent := make([]int, n+1)
blocked := make([]bool, n+1)
tail := make([]int, m+1)
for i := 0; i < k; i++ {
a := nextInt()
b := nextInt()
if !blocked[a] && tail[b] != 0 {
parent[a] = tail[b]
blocked[a] = true
}
tail[b] = a
}
children := make([][]int, n+1)
for i := 1; i <= n; i++ {
if parent[i] != 0 {
children[parent[i]] = append(children[parent[i]], i)
}
}
tin := make([]int, n+1)
tout := make([]int, n+1)
sz := make([]int, n+1)
timer := 0
stackNode := make([]int, 0, n)
stackIdx := make([]int, 0, n)
for i := 1; i <= n; i++ {
if parent[i] != 0 {
continue
}
stackNode = append(stackNode, i)
stackIdx = append(stackIdx, 0)
for len(stackNode) > 0 {
v := stackNode[len(stackNode)-1]
idx := stackIdx[len(stackIdx)-1]
if idx == 0 {
timer++
tin[v] = timer
sz[v] = 1
}
if idx < len(children[v]) {
u := children[v][idx]
stackIdx[len(stackIdx)-1]++
stackNode = append(stackNode, u)
stackIdx = append(stackIdx, 0)
} else {
tout[v] = timer
stackNode = stackNode[:len(stackNode)-1]
stackIdx = stackIdx[:len(stackIdx)-1]
if parent[v] != 0 {
sz[parent[v]] += sz[v]
}
}
}
}
out := make([]byte, 0, q*4)
for i := 0; i < q; i++ {
x := nextInt()
y := nextInt()
z := tail[y]
if z != 0 && tin[x] <= tin[z] && tout[z] <= tout[x] {
out = strconv.AppendInt(out, int64(sz[x]), 10)
} else {
out = append(out, '0')
}
out = append(out, '\n')
}
w := bufio.NewWriterSize(os.Stdout, 1<<20)
w.Write(out)
w.Flush()
}
```