← Home
```go
package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	var s, p string
	fmt.Fscan(reader, &s)
	fmt.Fscan(reader, &p)

	n := len(s)
	m := len(p)

	// Precompute: for each position i in s, and each position j in p,
	// what is the minimum number of characters we need to skip in s
	// starting from position i to match pattern p, given we already matched j characters?
	// Actually, let's think differently.

	// For each position i in s, compute the minimum number of deletions needed
	// to match pattern p starting at position i in s.
	// matchCost[i] = minimum number of characters to delete from s[i..] to match p as a substring starting at i
	// More precisely: minimum deletions from s[i..i+k-1] such that after deletion we get p,
	// where k is the length of the segment we consume from s.

	// Let's define: cost[i] = minimum number of characters consumed from s starting at position i
	// to form pattern p, and deletions = consumed - m.
	// We want to find for each starting position i, the minimum number of characters from s
	// we need to consume to match all of p.

	// consume[i] = minimum number of characters of s starting from position i needed to match p
	// If it's impossible, consume[i] = infinity
	// deletions to match p starting at i = consume[i] - m

	consume := make([]int, n)
	for i := 0; i < n; i++ {
		consume[i] = -1 // impossible
		pi := 0
		for j := i; j < n && pi < m; j++ {
			if s[j] == p[pi] {
				pi++
			}
			if pi == m {
				consume[i] = j - i + 1
			}
		}
	}

	// Now DP:
	// dp[i][j] = maximum number of pattern matches using s[0..i-1] with exactly j deletions
	// This is tricky because we need exact deletions.

	// Let's define dp[i][j] = max occurrences of p we can get considering s[0..i-1] with j characters deleted so far.
	// Transition:
	// 1) Delete s[i-1]: dp[i][j] = dp[i-1][j-1] (if j >= 1)
	// 2) Keep s[i-1] but don't start a pattern match here... but this is complicated
	//    because "keeping" characters that aren't part of a match will remain in s'.

	// Actually, let me reconsider. We remove exactly x characters. The remaining string s' is a subsequence of s.
	// We want max non-overlapping occurrences of p in s'.

	// dp[i][j] = maximum occurrences using first i characters of s, having removed j characters so far.
	// At position i (1-indexed), we either remove s[i] (cost 1 deletion) or keep it.
	// If we keep it, it becomes part of s'. We can also try to match pattern p ending around here.

	// Better approach: dp[i][j] = max occ considering s[0..i-1], removed j chars.
	// Option 1: remove char i -> dp[i][j] = dp[i-1][j-1]
	// Option 2: keep char i (no match starts/completes) -> dp[i][j] = dp[i-1][j] ... but this isn't right either since kept chars just sit in s'.
	// Option 3: match pattern p ending at position i. If consume[start] = len, we consume s[start..i-1], 
	//   delete (len - m) of them, keep m. dp[i][j] = dp[start][j - (len-m)] + 1

	const NEG_INF = -1 << 30

	dp := make([][]int, n+1)
	for i := 0; i <= n; i++ {
		dp[i] = make([]int, n+1)
		for j := 0; j <= n; j++ {
			dp[i][j] = NEG_INF
		}
	}
	dp[0][0] = 0

	for i := 1; i <= n; i++ {
		for j := 0; j <= i; j++ {
			// Option 1: remove s[i-1]
			if j >= 1 && dp[i-1][j-1] != NEG_INF {
				dp[i][j] = max(dp[i][j], dp[i-1][j-1])
			}
			// Option 2: keep s[i-1], no pattern match ending here
			if dp[i-1][j] != NEG_INF {
				dp[i][j] = max(dp[i][j], dp[i-1][j])
			}
			// Option 3: match pattern ending at position i
			// We need some start position k where consume[k] exists, and k + consume[k] == i
			// deletions from this match = consume[k] - m
			// so j must be >= consume[k] - m, and dp[k][j-(consume[k]-m)] must be valid
			for k := 0; k < i; k++ {
				if consume[k] > 0 && k+consume[k] == i {
					del := consume[k] - m
					if j >= del && dp[k][j-del] != NEG_INF {
						dp[i][j] = max(dp[i][j], dp[k][j-del]+1)
					}
				}
			}
		}
	}

	ans := make([]int, n+1)
	for x := 0; x <= n; x++ {
		ans[x] = 0
		if dp[n][x] > 0 {
			ans[x] = dp[n][x]
		}
	}

	parts := make([]string, n+1)
	for i := 0; i <= n; i++ {
		parts[i] = fmt.Sprintf("%d", ans[i])
	}
	fmt.Println(strings.Join(parts, " "))
}

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}
```