← Home
```go
package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)

	var n, d int
	fmt.Fscan(reader, &n, &d)

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

	// dp[pos][offset] where offset is the deviation from d: -1, 0, +1
	// At position pos with jump length (d + offset), the max gems collected
	// We remap offset: -1 -> 0, 0 -> 1, +1 -> 2
	// But pos can be up to 30000 and we need to track the offset from d
	// The offset can drift over time, but bounded roughly by sqrt(30000) steps
	// Actually offset can range from about -250 to +250 roughly
	// More precisely, after k jumps, offset ranges from -k to +k, and position ~ k*d + sum of offsets
	// Position <= 30000, k <= 30000/d (roughly), so offset range ~ 30000/d
	// We need offset range. Let's use offset range [-250, 250] to be safe... 
	// Actually worst case d=1, then up to 30000 jumps, offset could be -30000 to 30000
	// But jump length must be positive, so if d=1 after k steps, length = 1+offset >= 1, offset >= 0
	// Hmm, let me think differently.
	
	// Let's use dp[pos][delta] where delta = (current_jump_length - d), mapped with an offset
	// delta can range from -(something) to +(something)
	// Since jump length must be >= 1 and position <= 30000, jump length <= 30000
	// delta ranges from (1-d) to 30000
	// That's too large for d=1.
	
	// Better approach: only track delta in range [-250, 250] or similar
	// After k steps, delta ranges from -k to k. Position after k steps = k*d + sum of deltas accumulated
	// sum of deltas can be at most k*(k+1)/2. For position <= 30000 and d steps:
	// k*d <= 30000 + k*(k+1)/2, so k <= 30000/d + ...
	// The key insight: delta changes by at most 1 per step, so after k steps |delta| <= k
	// And k*1 <= position <= 30000, so k <= 30000
	// But delta bounded by: jump_length = d + delta >= 1, so delta >= 1-d
	// For d large, delta is small. For d=1, delta >= 0 always.
	// Let's bound: |delta| <= 250 should work because position grows quadratically with delta drift.
	
	const MAXPOS = 30001
	const OFFSET = 250
	const WIDTH = 2*OFFSET + 1

	// dp[pos][delta+OFFSET]
	// Use a flat array
	dp := make([][]int32, MAXPOS)
	for i := range dp {
		dp[i] = make([]int32, WIDTH)
		for j := range dp[i] {
			dp[i][j] = -1
		}
	}

	dp[d][OFFSET] = int32(gems[d])
	ans := int32(gems[d])

	for pos := d; pos < MAXPOS; pos++ {
		for di := 0; di < WIDTH; di++ {
			if dp[pos][di] < 0 {
				continue
			}
			cur := dp[pos][di]
			delta := di - OFFSET
			jumpLen := d + delta // length of jump that got us here
			// Next jump can be jumpLen-1, jumpLen, jumpLen+1
			for _, nl := range []int{jumpLen - 1, jumpLen, jumpLen + 1} {
				if nl <= 0 {
					continue
				}
				npos := pos + nl
				if npos >= MAXPOS {
					continue
				}
				ndelta := nl - d
				ndi := ndelta + OFFSET
				if ndi < 0 || ndi >= WIDTH {
					continue
				}
				val := cur + int32(gems[npos])
				if val > dp[npos][ndi] {
					dp[npos][ndi] = val
				}
				if val > ans {
					ans = val
				}
			}
		}
	}

	fmt.Println(ans)
}
```