← Home
```go
package main

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

func main() {
	reader := bufio.NewReader(os.Stdin)
	writer := bufio.NewWriter(os.Stdout)
	defer writer.Flush()

	var n int
	fmt.Fscan(reader, &n)
	var s string
	fmt.Fscan(reader, &s)

	// Precompute: for each character c and each (i,j) pair, cost[c][i][j] = number of non-c characters in s[i..j]
	// Then best[c][m] = maximum window length where cost <= m
	// We precompute best[26][n+1]

	best := [26][1501]int{}

	for c := 0; c < 26; c++ {
		ch := byte('a' + c)
		// sliding window or precompute prefix sums
		// prefix[i] = number of non-ch characters in s[0..i-1]
		prefix := make([]int, n+1)
		for i := 0; i < n; i++ {
			prefix[i+1] = prefix[i]
			if s[i] != ch {
				prefix[i+1]++
			}
		}
		// For each m from 0 to n, find max length window with at most m non-ch chars
		// Use two pointers
		// best[c][m] = max window length with cost <= m
		// First compute for all possible windows
		// best[c][m] for m=0..n
		// Initialize
		for m := 0; m <= n; m++ {
			best[c][m] = 0
		}
		// Two pointer for each m would be O(n) per m -> O(26*n^2) total which might be too slow for n=1500
		// Better: precompute maxLen[cost] = max window length with exactly 'cost' non-ch chars
		// Then best[c][m] = max(maxLen[0..m])
		
		// Actually let's compute for each window its cost and update
		// Use sliding window: for each right, find leftmost left such that cost <= m
		// But we need all m values
		
		// Alternative: for each pair (l, r), cost = prefix[r+1] - prefix[l]
		// We want max (r-l+1) = max (r+1-l) for each cost value
		// maxByExactCost[k] = max window length with exactly k non-ch chars
		maxByExactCost := make([]int, n+1)
		
		left := 0
		for right := 0; right < n; right++ {
			// cost of window [left, right] = prefix[right+1] - prefix[left]
			// We want to track for each possible cost (0..n) the max length
			// Actually easier: use sliding window to find for each right the min left for cost <= m
			// But let's just compute all windows
			_ = left
		}
		_ = left
		
		// Reset and do O(n^2) precomputation
		for i := 0; i < n; i++ {
			cost := 0
			for j := i; j < n; j++ {
				if s[j] != ch {
					cost++
				}
				length := j - i + 1
				if maxByExactCost[cost] < length {
					maxByExactCost[cost] = length
				}
			}
		}
		
		// Now best[c][m] = max over k=0..m of maxByExactCost[k]
		best[c][0] = maxByExactCost[0]
		for m := 1; m <= n; m++ {
			best[c][m] = best[c][m-1]
			if maxByExactCost[m] > best[c][m] {
				best[c][m] = maxByExactCost[m]
			}
		}
		
		// Reset maxByExactCost for next character
		for i := range maxByExactCost {
			maxByExactCost[i] = 0
		}
	}

	var q int
	fmt.Fscan(reader, &q)
	for ; q > 0; q-- {
		var m int
		var cs string
		fmt.Fscan(reader, &m, &cs)
		c := int(cs[0] - 'a')
		fmt.Fprintln(writer, best[c][m])
	}
}
```