← Home
```go
package main

import (
	"bufio"
	"io"
	"math/bits"
	"os"
	"sort"
	"strconv"
)

type Quest struct {
	x int32
	y int32
	t int32
}

func abs32(x int32) int32 {
	if x < 0 {
		return -x
	}
	return x
}

func manhattan(x1, y1, x2, y2 int32) int32 {
	return abs32(x1-x2) + abs32(y1-y2)
}

func buildActive(state []uint16, totalMasks, blocks int, out []int) []int {
	out = out[:0]
	for mask := 0; mask < totalMasks; mask++ {
		off := mask * blocks
		for b := 0; b < blocks; b++ {
			if state[off+b] != 0 {
				out = append(out, mask)
				break
			}
		}
	}
	return out
}

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()

	tx := make([]int32, n)
	ty := make([]int32, n)
	for i := 0; i < n; i++ {
		tx[i] = int32(nextInt())
		ty[i] = int32(nextInt())
	}

	quests := make([]Quest, m)
	for i := 0; i < m; i++ {
		quests[i] = Quest{
			x: int32(nextInt()),
			y: int32(nextInt()),
			t: int32(nextInt()),
		}
	}

	sort.Slice(quests, func(i, j int) bool {
		return quests[i].t < quests[j].t
	})

	qx := make([]int32, m)
	qy := make([]int32, m)
	qtm := make([]int32, m)
	for i := 0; i < m; i++ {
		qx[i] = quests[i].x
		qy[i] = quests[i].y
		qtm[i] = quests[i].t
	}

	blocks := (m + 15) >> 4
	totalMasks := 1 << n
	fullMask := totalMasks - 1
	const INF int32 = 2000000000

	qToTower := make([]int32, m*n)
	for i := 0; i < m; i++ {
		for e := 0; e < n; e++ {
			qToTower[i*n+e] = manhattan(qx[i], qy[i], tx[e], ty[e])
		}
	}

	tToT := make([]int32, n*n)
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			tToT[i*n+j] = manhattan(tx[i], ty[i], tx[j], ty[j])
		}
	}

	walkAdj := make([]uint16, m*blocks)
	for i := 0; i < m; i++ {
		base := i * blocks
		for j := i + 1; j < m; j++ {
			if manhattan(qx[i], qy[i], qx[j], qy[j]) <= qtm[j]-qtm[i] {
				walkAdj[base+(j>>4)] |= uint16(1) << uint(j&15)
			}
		}
	}

	lsbi := make([]uint8, 1<<16)
	for i := 1; i < 1<<16; i++ {
		lsbi[i] = uint8(bits.TrailingZeros16(uint16(i)))
	}

	timeTable := make([]int32, blocks*(1<<16))
	for i := range timeTable {
		timeTable[i] = INF
	}

	walkOr := make([]uint16, blocks*(1<<16)*blocks)

	for b := 0; b < blocks; b++ {
		for mask := 1; mask < (1 << 16); mask++ {
			prev := mask & (mask - 1)
			q := b*16 + int(lsbi[mask])

			prevTime := timeTable[(b<<16)+prev]
			valTime := INF
			if q < m {
				valTime = qtm[q]
			}
			if valTime < prevTime {
				timeTable[(b<<16)+mask] = valTime
			} else {
				timeTable[(b<<16)+mask] = prevTime
			}

			curW := ((b << 16) + mask) * blocks
			prevW := ((b << 16) + prev) * blocks
			if q < m {
				adjBase := q * blocks
				for ob := 0; ob < blocks; ob++ {
					walkOr[curW+ob] = walkOr[prevW+ob] | walkAdj[adjBase+ob]
				}
			} else {
				for ob := 0; ob < blocks; ob++ {
					walkOr[curW+ob] = walkOr[prevW+ob]
				}
			}
		}
	}

	towerTable := make([]int32, n*blocks*(1<<16))
	for i := range towerTable {
		towerTable[i] = INF
	}
	for e := 0; e < n; e++ {
		for b := 0; b < blocks; b++ {
			base := ((e*blocks + b) << 16)
			for mask := 1; mask < (1 << 16); mask++ {
				prev := mask & (mask - 1)
				q := b*16 + int(lsbi[mask])

				prevVal := towerTable[base+prev]
				val := INF
				if q < m {
					val = qtm[q] + qToTower[q*n+e]
				}
				if val < prevVal {
					towerTable[base+mask] = val
				} else {
					towerTable[base+mask] = prevVal
				}
			}
		}
	}

	near := make([]int32, totalMasks*n)
	if n > 0 {
		for e := 0; e < n; e++ {
			near[e] = INF
		}
	}
	reachThresh := make([]int32, totalMasks*m)

	for mask := 1; mask < totalMasks; mask++ {
		prev := mask & (mask - 1)
		bit := int(lsbi[mask])

		nb := mask * n
		tb := bit * n
		if prev == 0 {
			for e := 0; e < n; e++ {
				near[nb+e] = tToT[tb+e]
			}
		} else {
			pb := prev * n
			for e := 0; e < n; e++ {
				v := tToT[tb+e]
				pv := near[pb+e]
				if v < pv {
					near[nb+e] = v
				} else {
					near[nb+e] = pv
				}
			}
		}

		rb := mask * m
		if prev == 0 {
			for j := 0; j < m; j++ {
				reachThresh[rb+j] = qtm[j] - qToTower[j*n+bit]
			}
		} else {
			pb := prev * m
			for j := 0; j < m; j++ {
				v := qtm[j] - qToTower[j*n+bit]
				pv := reachThresh[pb+j]
				if v > pv {
					reachThresh[rb+j] = v
				} else {
					reachThresh[rb+j] = pv
				}
			}
		}
	}

	stateSize := totalMasks * blocks
	cur := make([]uint16, stateSize)
	next := make([]uint16, stateSize)
	seed := make([]int32, totalMasks)
	distTower := make([]int32, totalMasks)

	for j := 0; j < m; j++ {
		cur[j>>4] |= uint16(1) << uint(j&15)
	}

	if n > 0 {
		for i := 0; i < totalMasks; i++ {
			seed[i] = INF
		}
		for e := 0; e < n; e++ {
			seed[1<<e] = 0
		}
		for mask := 1; mask < totalMasks; mask++ {
			distTower[mask] = seed[mask]
		}
		for mask := 1; mask < totalMasks; mask++ {
			d := distTower[mask]
			if d == INF {
				continue
			}
			rem := fullMask ^ mask
			nb := mask * n
			for rem != 0 {
				lb := rem & -rem
				e := int(lsbi[lb])
				nm := mask | lb
				nd := d + near[nb+e]
				if nd < distTower[nm] {
					distTower[nm] = nd
				}
				rem ^= lb
			}
		}
		for mask := 1; mask < totalMasks; mask++ {
			arr := distTower[mask]
			if arr == INF {
				continue
			}
			off := mask * blocks
			rb := mask * m
			for j := 0; j < m; j++ {
				if arr <= reachThresh[rb+j] {
					cur[off+(j>>4)] |= uint16(1) << uint(j&15)
				}
			}
		}
	}

	activeCur := make([]int, 0, totalMasks)
	activeNext := make([]int, 0, totalMasks)
	activeCur = buildActive(cur, totalMasks, blocks, activeCur)

	ans := 1

	for ans < m {
		for i := range next {
			next[i] = 0
		}
		for i := range seed {
			seed[i] = INF
		}

		for _, mask := range activeCur {
			off := mask * blocks
			var mins [14]int32
			for e := 0; e < n; e++ {
				mins[e] = INF
			}
			mnTime := INF

			for b := 0; b < blocks; b++ {
				bitsBlock := cur[off+b]
				if bitsBlock == 0 {
					continue
				}

				idxBlock := (b << 16) + int(bitsBlock)

				tv := timeTable[idxBlock]
				if tv < mnTime {
					mnTime = tv
				}

				baseW := idxBlock * blocks
				for ob := 0; ob < blocks; ob++ {
					next[off+ob] |= walkOr[baseW+ob]
				}

				for e := 0; e < n; e++ {
					v := towerTable[(((e*blocks)+b)<<16)+int(bitsBlock)]
					if v < mins[e] {
						mins[e] = v
					}
				}
			}

			if mask != 0 && mnTime < seed[mask] {
				seed[mask] = mnTime
			}

			rem := fullMask ^ mask
			for rem != 0 {
				lb := rem & -rem
				e := int(lsbi[lb])
				v := mins[e]
				nm := mask | lb
				if v < seed[nm] {
					seed[nm] = v
				}
				rem ^= lb
			}
		}

		if n > 0 {
			for mask := 1; mask < totalMasks; mask++ {
				distTower[mask] = seed[mask]
			}
			for mask := 1; mask < totalMasks; mask++ {
				d := distTower[mask]
				if d == INF {
					continue
				}
				rem := fullMask ^ mask
				nb := mask * n
				for rem != 0 {
					lb := rem & -rem
					e := int(lsbi[lb])
					nm := mask | lb
					nd := d + near[nb+e]
					if nd < distTower[nm] {
						distTower[nm] = nd
					}
					rem ^= lb
				}
			}
			for mask := 1; mask < totalMasks; mask++ {
				arr := distTower[mask]
				if arr == INF {
					continue
				}
				off := mask * blocks
				rb := mask * m
				for j := 0; j < m; j++ {
					if arr <= reachThresh[rb+j] {
						next[off+(j>>4)] |= uint16(1) << uint(j&15)
					}
				}
			}
		}

		activeNext = buildActive(next, totalMasks, blocks, activeNext)
		if len(activeNext) == 0 {
			break
		}

		ans++
		cur, next = next, cur
		activeCur, activeNext = activeNext, activeCur[:0]
	}

	w := bufio.NewWriterSize(os.Stdout, 32)
	w.WriteString(strconv.Itoa(ans))
	w.Flush()
}
```