← Home
Looking at this problem, I need to find the maximum number of attribute checks I can pass by optimally distributing points between Strength and Intelligence.

Key observations:
- There are exactly m points (zeros), where m ≤ 5000
- n can be up to 2×10⁶
- At each check, the number of points spent so far is fixed (it's the count of zeros before that check)
- If k points have been spent before a check, and we allocated s to Strength and k-s to Intelligence, then s + (k-s) = k

Let me think of this differently. Let's number the points 1 to m. After point j is allocated, we have j total points distributed. For each check, we know how many points have been allocated before it (the count of zeros before it).

For a check at position with `pts` points allocated before it:
- If it's an intelligence check with value `v > 0`: we need intelligence ≥ v, meaning points to intel ≥ v, meaning points to strength ≤ pts - v
- If it's a strength check with value `|v|` (r_i < 0): we need strength ≥ |v|, meaning points to strength ≥ |v|

So each check constrains the number of strength points at that moment. We want to maximize the number of checks we pass.

Since m ≤ 5000, we can think about DP over subsets of checks. But that's too large.

Let me think about it as: we choose how many strength points after each of the m point acquisitions. Let s_j = total strength points after the j-th zero (cumulative). s_0 = 0, s_j is non-decreasing, 0 ≤ s_j ≤ j.

Each check after the j-th zero (and before the (j+1)-th zero) with value r requires:
- If r < 0: s_j ≥ |r|
- If r > 0: s_j ≤ j - r (i.e., intelligence = j - s_j ≥ r)

We want to maximize checks passed. Since m ≤ 5000, we can do DP on s_j.

DP state: dp[j][s] = max checks passed considering the first j points, with s points in strength after j-th point.

Transitions: dp[j][s] = max over s' ≤ s of dp[j-1][s'] + (number of checks between point j-1 and point j that are satisfied with s' strength points) + (number of checks after point j that... wait, checks between point j and point j+1 depend on s).

Let me redefine: checks between the j-th and (j+1)-th point depend on s_j = s. So:

dp[j][s] = max over s' ≤ s { dp[j-1][s'] } + bonus(j, s)

where bonus(j, s) = number of checks between point j and point j+1 that are satisfied when strength = s, intelligence = j - s.

This is O(m²) states with O(m) transition each = O(m³) which is too slow for m=5000.

But the transition is dp[j][s] = max_{s' ≤ s} dp[j-1][s'] + bonus(j,s), which is just prefix max of dp[j-1] plus bonus. So it's O(m²)!

For each j, compute prefix max of dp[j-1], then dp[j][s] = prefmax[s] + bonus(j, s).

This is O(m²) time and space, which for m=5000 is 25 million — feasible.

Now I need to precompute bonus(j, s) for each j from 0 to m and each s from 0 to j.

For checks between point j and point j+1 with `pts = j`:
- strength check |r|: satisfied if s ≥ |r|
- intelligence check r: satisfied if j - s ≥ r, i.e., s ≤ j - r

For each group j, I can compute bonus(j, s) efficiently.

```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscan(reader, &n, &m)

	r := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &r[i])
	}

	// Group checks by how many points before them
	// bonus[j] will store the checks that occur when pts = j
	// For each group, compute bonus(j, s) using prefix sums

	checks := make([][]int, m+1) // checks[j] = list of r_i for checks after j-th point
	for i := 0; i <= m; i++ {
		checks[i] = []int{}
	}
	pts := 0
	for i := 0; i < n; i++ {
		if r[i] == 0 {
			pts++
		} else {
			checks[pts] = append(checks[pts], r[i])
		}
	}

	dp := make([]int, m+1)
	for s := 0; s <= m; s++ {
		dp[s] = -1
	}
	dp[0] = 0

	// Add bonus for j=0
	bonus := computeBonus(0, checks[0])
	for s := 0; s <= 0; s++ {
		if dp[s] >= 0 {
			dp[s] += bonus[s]
		}
	}

	for j := 1; j <= m; j++ {
		ndp := make([]int, m+1)
		for s := 0; s <= m; s++ {
			ndp[s] = -1
		}
		// prefix max of dp
		pmx := make([]int, m+1)
		pmx[0] = dp[0]
		for s := 1; s <= m; s++ {
			pmx[s] = pmx[s-1]
			if dp[s] > pmx[s] {
				pmx[s] = dp[s]
			}
		}
		bon := computeBonus(j, checks[j])
		for s := 0; s <= j; s++ {
			if pmx[s] >= 0 {
				ndp[s] = pmx[s] + bon[s]
			}
		}
		dp = ndp
	}

	ans := 0
	for s := 0; s <= m; s++ {
		if dp[s] > ans {
			ans = dp[s]
		}
	}
	fmt.Println(ans)
}

func computeBonus(j int, chks []int) []int {
	bonus := make([]int, j+1)
	// For each check in chks:
	// r < 0 (strength): pass if s >= |r|  → add 1 to bonus[|r|..j]
	// r > 0 (intel): pass if s <= j - r   → add 1 to bonus[0..j-r]
	// Use difference array
	diff := make([]int, j+2)
	for _, c := range chks {
		if c < 0 {
			need := -c
			if need <= j {
				diff[need]++
				diff[j+1]--
			}
		} else {
			upper := j - c
			if upper >= 0 {
				diff[0]++
				diff[upper+1]--
			}
		}
	}
	cur := 0
	for s := 0; s <= j; s++ {
		cur += diff[s]
		bonus[s] = cur
	}
	return bonus
}
```

Wait, let me reconsider the memory. dp has size m+1 which is fine. But computeBonus allocates arrays each time. Let me optimize.

Actually for m=5000, this should be fine. Let me verify the logic once more and clean up.

```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscan(reader, &n, &m)

	r := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &r[i])
	}

	checks := make([][]int, m+1)
	pts := 0
	for i := 0; i < n; i++ {
		if r[i] == 0 {
			pts++
		} else {
			checks[pts] = append(checks[pts], r[i])
		}
	}

	dp := make([]int, m+1)
	for i := range dp {
		dp[i] = -1
	}
	dp[0] = computeBonusVal(0, checks[0], 0)

	for j := 1; j <= m; j++ {
		ndp := make([]int, m+1)
		for i := range ndp {
			ndp[i] = -1
		}
		mx := dp[0]
		for s := 0; s <= j; s++ {
			if s > 0 && dp[s] > mx {
				mx = dp[s]
			}
			if mx >= 0 {
				bon := computeBonusVal(j, checks[j], s)
				ndp[s] = mx + bon
			}
		}
		dp = ndp
	}

	ans := 0
	for s := 0; s <= m; s++ {
		if dp[s] > ans {
			ans = dp[s]
		}
	}
	fmt.Println(ans)
}

func computeBonusVal(j int, chks []int, s int) int {
	cnt := 0
	for _, c := range chks {
		if c < 0 {
			if s >= -c {
				cnt++
			}
		} else {
			if j-s >= c {
				cnt++
			}
		}
	}
	return cnt
}
```

Hmm but this is O(m² * avg_checks) which could be O(m² * n/m) = O(m*n) which is 5000 * 2e6 = 1e10. Too slow.

I need to use the difference array approach. Let me go back to the first approach but precompute bonus arrays properly.

```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscan(reader, &n, &m)

	r := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &r[i])
	}

	// Group checks by point count before them
	type checkInfo struct{ val int }
	checks := make([][]int, m+1)
	pts := 0
	for i := 0; i < n; i++ {
		if r[i] == 0 {
			pts++
		} else {
			checks[pts] = append(checks[pts], r[i])
		}
	}

	// Precompute bonus arrays using difference arrays
	// bonus[j][s] for s in [0..j]
	dp := make([]int, m+1)
	for i := range dp {
		dp[i] = -1
	}

	// Compute bonus for j=0
	bon0 := makeBonusArray(0, checks[0])
	dp[0] = bon0[0]

	for j := 1; j <= m; j++ {
		bon := makeBonusArray(j, checks[j])
		ndp := make([]int, m+1)
		for i := range ndp {
			ndp[i] = -1
		}
		// prefix max of dp over [0..s]
		mx := dp[0]
		for s := 0; s <= j; s++ {
			if s > 0 && dp[s] > mx {
				mx = dp[s]
			}
			if mx >= 0 {
				ndp[s] = mx + bon[s]
			}
		}
		dp = ndp
	}

	ans := 0
	for s := 0; s <= m; s++ {
		if dp[s] > ans {
			ans = dp[s]
		}
	}
	fmt.Println(ans)
}

func makeBonusArray(j int, chks []int) []int {
	bonus := make([]int, j+1)
	if len(chks) == 0 {
		return bonus
	}
	diff := make([]int, j+2)
	for _, c := range chks {
		if c < 0 {
			need := -c
			if need <= j {
				diff[need]++
				if j+1 < len(diff) {
					diff[j+1]--
				}
			}
		} else {
			upper := j - c
			if upper >= 0 {
				diff[0]++
				if upper+1 < len(diff) {
					diff[upper+1]--
				}
			}
		}
	}
	cur := 0
	for s := 0; s <= j; s++ {
		cur += diff[s]
		bonus[s] = cur
	}
	return bonus
}
```

This should be O(n + m²) overall. The makeBonusArray calls take O(total_checks + sum of j) = O(n + m²). The DP transitions take O(m²). Total: O(n + m²) which is about 2e6 + 25e6 = fine.

But memory: we're allocating bonus arrays of size up to m+1 for each j, but we only use them once. That's fine since they're temporary.

Let me verify with examples and submit.

Example 1: `0 1 0 2 0 -3 0 -4 0 -5` → checks[0]=[], checks[1]=[1], checks[2]=[2], checks[3]=[-3], checks[4]=[-4], checks[5]=[-5]
All strength → s=5 at end. Check 1 (intel, need 1, pts=1, s=1): 1-1=0 < 1, fail. Check 2 (intel, need 2, pts=2, s=2): 2-2=0 < 2, fail. Check -3 (str, need 3, pts=3, s=3): pass. Check -4 (str, need 4, pts=4, s=4): pass. Check -5 (str, need 5, pts=5, s=5): pass. Total=3. ✓

Let me code this properly:

```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscan(reader, &n, &m)

	r := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &r[i])
	}

	checks := make([][]int, m+1)
	pts := 0
	for i := 0; i < n; i++ {
		if r[i] == 0 {
			pts++
		} else {
			checks[pts] = append(checks[pts], r[i])
		}
	}

	// dp[s] = max checks passed with s strength points allocated so far
	dp := make([]int, m+1)
	for i := range dp {
		dp[i] = -1
	}

	// j=0: bonus for having 0 points total, s=0
	b := 0
	for _, c := range checks[0] {
		_ = c // with 0 points, can't pass anything with positive requirement
		// Actually if c > 0, need intel >= c, intel = 0 - 0 = 0, fail if c > 0
		// If c < 0, need str >= |c|, str = 0, fail if |c| > 0
		// So bonus is 0
	}
	dp[0] = b

	for j := 1; j <= m; j++ {
		// Compute bonus array for group j
		chks := checks[j]
		diff := make([]int, j+2)
		for _, c := range chks {
			if c < 0 {
				need := -c
				if need <= j {
					diff[need]++
					diff[j+1]--
				}
			} else {
				upper := j - c
				if upper >= 0 {
					diff[0]++
					diff[upper+1]--
				}
			}
		}
		bon := make([]int, j+1)
		cur := 0
		for s := 0; s <= j; s++ {
			cur += diff[s]
			bon[s] = cur
		}

		ndp := make([]int, m+1)
		for i := range ndp {
			ndp[i] = -1
		}
		mx := -1
		for s := 0; s <= j; s++ {
			if dp[s] > mx {
				mx = dp[s]
			}
			// Also dp[s] from previous could have s <= j-1, which is fine since s <= j
			// But dp[s] is defined for s <= j-1 from previous round
			if mx >= 0 {
				ndp[s] = mx + bon[s]
			}
		}
		dp = ndp
	}

	ans := 0
	for s := 0; s <= m; s++ {
		if dp[s] > ans {
			ans = dp[s]
		}
	}
	fmt.Println(ans)
}
```

Wait, I realize the j=0 case needs special handling. When j=0 (before any points), s must be 0. The bonus for checks[0] with s=0, j=0: for any check c, if c>0 need intel ≥ c but intel=0, fail. If c<0 need str ≥ |c| but str=0, fail. So dp[0]=0.

Actually let me reconsider. At j=0, we have 0 points allocated. The checks in checks[0] happen before any point. s=0, intel=0. No check can be passed (since all checks have |r_i| ≥ 1). So dp[0] = 0.

Hmm wait, can |r_i| be 0? No, r_i=0 means point acquisition. So checks have |r_i| ≥ 1. Good.

Let me trace example 3: `0 0 1 0 2 -3 -2 -2 1`, m=3
- checks[0] = [] (before first 0, nothing)
- After 1st zero (j=1): nothing before next zero
- checks[1] = [] (between 1st and 2nd zero, nothing)  

Wait let me re-trace. The sequence is: 0, 0, 1, 0, 2, -3, -2, -2, 1

pts starts at 0.
- r[0]=0: pts becomes 1
- r[1]=0: pts becomes 2
- r[2]=1: checks[2] gets 1
- r[3]=0: pts becomes 3
- r[4]=2: checks[3] gets 2
- r[5]=-3: checks[3] gets -3
- r[6]=-2: checks[3] gets -2
- r[7]=-2: checks[3] gets -2
- r[8]=1: checks[3] gets 1

So checks[0]=[], checks[1]=[], checks[2]=[1], checks[3]=[2,-3,-2,-2,1]

j=0: dp[0]=0
j=1: bon for checks[1]=[]: all zeros. mx at s=0: dp[0]=0. ndp[0]=0+0=0. ndp[1]: mx=max(dp[0],dp[1])=max(0,-1)=0, bon[1]=0, ndp[1]=0.
j=2: checks[2]=[1]. diff for c=1 (intel): upper=2-1=1. diff[0]++, diff[2]--. So diff=[1,0,-1]. bon[0]=1, bon[1]=1, bon[2]=0.
mx starts -1. s=0: dp[0]=0>-1, mx=0. ndp[0]=0+1=1. s=1: dp[1]=0, mx stays 0. ndp[1]=0+1=1. s=2: dp[2]=-1, mx stays 0. ndp[2]=0+0=0.

j=3: checks[3]=[2,-3,-2,-2,1].
diff size = j+2 = 5. For each check:
- c=2 (intel): upper=3-2=1. diff[0]++, diff[2]--.
- c=-3 (str): need=3, 3<=3. diff[3]++, diff[4]--.
- c=-2 (str): need=2, 2<=3. diff[2]++, diff[4]--.
- c=-2 (str): need=2, 2<=3. diff[2]++, diff[4]--.
- c=1 (intel): upper=3-1=2. diff[0]++, diff[3]--.

diff = [2, 0, 1, 0, -3] → wait let me recalculate:
diff[0] = 1+1 = 2
diff[1] = 0
diff[2] = -1+1+1 = 1
diff[3] = 1-1 = 0
diff[4] = -1-1-1 = -3 (but we don't use index 4 for bon)

bon[0] = 2, bon[1] = 2+0=2, bon[2] = 2+1=3, bon[3] = 3+0=3.

Now dp from j=2: dp[0]=1, dp[1]=1, dp[2]=0, rest -1.
mx starts -1.
s=0: dp[0]=1>-1, mx=1. ndp[0]=1+2=3.
s=1: dp[1]=1, mx stays 1. ndp[1]=1+2=3.
s=2: dp[2]=0, mx stays 1. ndp[2]=1+3=4.
s=3: dp[3]=-1, mx stays 1. ndp[3]=1+3=4.

ans = max(3,3,4,4) = 4. ✓

The solution works. Let me also verify the j=0 initialization handles checks[0] correctly in case there are checks before any points. In example 2: `1 -1 0`, m=1.
checks[0] = [1, -1], checks[1] = [].

j=0: dp[0] = 0 (no check can be passed with 0 points). ✓

Then j=1: bon for checks[1]=[]: all zeros. mx at s=0: dp[0]=0. ndp[0]=0, ndp[1]=0. ans=0. ✓

Great, the solution is correct. Let me write the final clean version:

```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscan(reader, &n, &m)

	r := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &r[i])
	}

	checks := make([][]int, m+1)
	pts := 0
	for i := 0; i < n; i++ {
		if r[i] == 0 {
			pts++
		} else {
			checks[pts] = append(checks[pts], r[i])
		}
	}

	dp := make([]int, m+1)
	for i := range dp {
		dp[i] = -1
	}
	dp[0] = 0

	for j := 1; j <= m; j++ {
		chks := checks[j]
		diff := make([]int, j+2)
		for _, c := range chks {
			if c < 0 {
				need := -c
				if need <= j {
					diff[need]++
					diff[j+1]--
				}
			} else {
				upper := j - c
				if upper >= 0 {
					diff[0]++
					diff[upper+1]--
				}
			}
		}
		bon := make([]int, j+1)
		cur := 0
		for s := 0; s <= j; s++ {
			cur += diff[s]
			bon[s] = cur
		}

		ndp := make([]int, m+1)
		for i := range ndp {
			ndp[i] = -1
		}
		mx := -1
		for s := 0; s <= j; s++ {
			if dp[s] > mx {
				mx = dp[s]
			}
			if mx >= 0 {
				ndp[s] = mx + bon[s]
			}
		}
		dp = ndp
	}

	ans := 0
	for s := 0; s <= m; s++ {
		if dp[s] > ans {
			ans = dp[s]
		}
	}
	fmt.Println(ans)
}
```

Hmm, but I'm concerned about the memory allocations in the loop (diff and bon arrays created each iteration, plus ndp). For m=5000, that's 5000 iterations each allocating arrays of size up to ~5002. Total allocation is O(m²) = 25M ints, which should be fine within 512MB.

Actually, I can optimize by reusing arrays. But let me also think about time complexity. The DP loop is O(m²). The diff/bon computation per j is O(|checks[j]| + j). Summing over all j: sum of |checks[j]| = n-m (total number of check records), and sum of j = O(m²). So total time is O(n + m²), which is about 2e6 + 25e6 ≈ 27e6 operations. Should be well within 2.5 seconds.

One concern: allocating `ndp` of size m+1 each iteration. That's 5001 ints × 5000 iterations = 25M allocations. In Go, this might be slow due to GC pressure. Let me use two pre-allocated arrays instead.

```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscan(reader, &n, &m)

	r := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscan(reader, &r[i])
	}

	checks := make([][]int, m+1)
	pts := 0
	for i := 0; i < n; i++ {
		if r[i] == 0 {
			pts++
		} else {
			checks[pts] = append(checks[pts], r[i])
		}
	}

	dp := make([]int, m+1)
	ndp := make([]int, m+1)
	diff := make([]int, m+2)
	bon := make([]int, m+1)

	for i := range dp {
		dp[i] = -1
	}
	dp[0] = 0

	for j := 1; j <= m; j++ {
		chks := checks[j]

		for s := 0; s <= j+1; s++ {
			diff[s] = 0
		}
		for _, c := range chks {
			if c < 0 {
				need := -c
				if need <= j {
					diff[need]++
					diff[j+1]--
				}
			} else {
				upper := j - c
				if upper >= 0 {
					diff[0]++
					diff[upper+1]--
				}
			}
		}
		cur := 0
		for s := 0; s <= j; s++ {
			cur += diff[s]
			bon[s] = cur
		}

		for i := 0; i <= m; i++ {
			ndp[i] = -1
		}
		mx := -1
		for s := 0; s <= j; s++ {
			if dp[s] > mx {
				mx = dp[s]
			}
			if mx >= 0 {
				ndp[s] = mx + bon[s]
			}
		}
		dp, ndp = ndp, dp
	}

	ans := 0
	for s := 0; s <= m; s++ {
		if dp[s] > ans {
			ans = dp[s]
		}
	}
	fmt.Println(ans)
}
```

This avoids all allocations in the loop. Should be fast enough.