package main
import (
"bufio"
"fmt"
"io"
"os"
"sort"
)
type Item struct {
d2 int64
p int64
r2 int64
}
const INF int64 = 1<<63 - 1
type SegTree struct {
n int
tree []int64
}
func NewSegTree(arr []int64) *SegTree {
st := &SegTree{n: len(arr), tree: make([]int64, 4*len(arr))}
if st.n > 0 {
st.build(1, 0, st.n-1, arr)
}
return st
}
func (st *SegTree) build(node, l, r int, arr []int64) {
if l == r {
st.tree[node] = arr[l]
return
}
m := (l + r) >> 1
st.build(node<<1, l, m, arr)
st.build(node<<1|1, m+1, r, arr)
if st.tree[node<<1] < st.tree[node<<1|1] {
st.tree[node] = st.tree[node<<1]
} else {
st.tree[node] = st.tree[node<<1|1]
}
}
func (st *SegTree) update(idx int, val int64) {
if st.n == 0 {
return
}
st.updateRec(1, 0, st.n-1, idx, val)
}
func (st *SegTree) updateRec(node, l, r, idx int, val int64) {
if l == r {
st.tree[node] = val
return
}
m := (l + r) >> 1
if idx <= m {
st.updateRec(node<<1, l, m, idx, val)
} else {
st.updateRec(node<<1|1, m+1, r, idx, val)
}
if st.tree[node<<1] < st.tree[node<<1|1] {
st.tree[node] = st.tree[node<<1]
} else {
st.tree[node] = st.tree[node<<1|1]
}
}
func (st *SegTree) query(l, r int) int64 {
if st.n == 0 {
return INF
}
return st.queryRec(1, 0, st.n-1, l, r)
}
func (st *SegTree) queryRec(node, l, r, ql, qr int) int64 {
if ql > r || qr < l {
return INF
}
if ql <= l && r <= qr {
return st.tree[node]
}
m := (l + r) >> 1
left := st.queryRec(node<<1, l, m, ql, qr)
right := st.queryRec(node<<1|1, m+1, r, ql, qr)
if left < right {
return left
}
return right
}
func (st *SegTree) findFirstLE(l, r int, thr int64) int {
if st.n == 0 {
return -1
}
return st.findRec(1, 0, st.n-1, l, r, thr)
}
func (st *SegTree) findRec(node, l, r, ql, qr int, thr int64) int {
if ql > r || qr < l || st.tree[node] > thr {
return -1
}
if l == r {
return l
}
m := (l + r) >> 1
res := st.findRec(node<<1, l, m, ql, qr, thr)
if res != -1 {
return res
}
return st.findRec(node<<1|1, m+1, r, ql, qr, thr)
}
func upperBound(a []int64, x int64) int {
return sort.Search(len(a), func(i int) bool { return a[i] > x })
}
func main() {
data, _ := io.ReadAll(os.Stdin)
idx := 0
nextInt := func() int64 {
n := int64(0)
sign := int64(1)
for idx < len(data) && (data[idx] <= ' ') {
idx++
}
if idx < len(data) && data[idx] == '-' {
sign = -1
idx++
}
for idx < len(data) && data[idx] >= '0' && data[idx] <= '9' {
n = n*10 + int64(data[idx]-'0')
idx++
}
return n * sign
}
x := nextInt()
y := nextInt()
p0 := nextInt()
r0 := nextInt()
n := int(nextInt())
massToItems := make(map[int64][]Item)
mvalsSet := make(map[int64]struct{})
for i := 0; i < n; i++ {
xi := nextInt()
yi := nextInt()
mi := nextInt()
pi := nextInt()
ri := nextInt()
dx := xi - x
dy := yi - y
d2 := dx*dx + dy*dy
r2 := ri * ri
massToItems[mi] = append(massToItems[mi], Item{d2: d2, p: pi, r2: r2})
mvalsSet[mi] = struct{}{}
}
mvals := make([]int64, 0, len(mvalsSet))
for k := range mvalsSet {
mvals = append(mvals, k)
}
sort.Slice(mvals, func(i, j int) bool { return mvals[i] < mvals[j] })
indexOf := make(map[int64]int, len(mvals))
for i, v := range mvals {
indexOf[v] = i
}
M := len(mvals)
groups := make([][]Item, M)
for m, items := range massToItems {
idx := indexOf[m]
group := items
sort.Slice(group, func(i, j int) bool { return group[i].d2 < group[j].d2 })
groups[idx] = group
}
ptr := make([]int, M)
arrMin := make([]int64, M)
for i := 0; i < M; i++ {
if len(groups[i]) > 0 {
arrMin[i] = groups[i][0].d2
} else {
arrMin[i] = INF
}
}
var seg *SegTree
if M > 0 {
seg = NewSegTree(arrMin)
}
type Rect struct {
P int64
R2 int64
}
queue := make([]Rect, 0, n+1)
R20 := r0 * r0
queue = append(queue, Rect{P: p0, R2: R20})
ans := 0
head := 0
for head < len(queue) {
cur := queue[head]
head++
if M == 0 {
continue
}
k := upperBound(mvals, cur.P)
if k == 0 {
continue
}
for seg.query(0, k-1) <= cur.R2 {
pos := seg.findFirstLE(0, k-1, cur.R2)
if pos == -1 {
break
}
it := groups[pos][ptr[pos]]
ptr[pos]++
ans++
queue = append(queue, Rect{P: it.p, R2: it.r2})
var newMin int64
if ptr[pos] < len(groups[pos]) {
newMin = groups[pos][ptr[pos]].d2
} else {
newMin = INF
}
seg.update(pos, newMin)
}
}
w := bufio.NewWriter(os.Stdout)
fmt.Fprintln(w, ans)
w.Flush()
}