← Home
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()
}