← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)

	readInt := func() int {
		scanner.Scan()
		val, _ := strconv.Atoi(scanner.Text())
		return val
	}

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())
	k := readInt()

	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = readInt()
	}

	sort.Ints(a)

	left := make([]int, n)
	l := 0
	for r := 0; r < n; r++ {
		for a[r]-a[l] > 5 {
			l++
		}
		left[r] = l
	}

	// dp[i] will store the maximum number of students using a subset of the first i students
	// with at most t-1 teams (from previous iteration).
	// nextDp[i] will store the result for at most t teams (current iteration).
	dp := make([]int, n+1)
	nextDp := make([]int, n+1)

	for t := 1; t <= k; t++ {
		nextDp[0] = 0
		for i := 1; i <= n; i++ {
			// Option 1: Don't include student i (index i-1) in a new team ending at i.
			// Inherit the best value found so far for the current number of teams.
			val1 := nextDp[i-1]

			// Option 2: Form a team ending at student i.
			// The team spans from left[i-1] to i-1.
			// We add the size of this team to the optimal solution using t-1 teams ending before this team.
			idx := i - 1
			start := left[idx]
			count := idx - start + 1
			val2 := dp[start] + count

			if val1 > val2 {
				nextDp[i] = val1
			} else {
				nextDp[i] = val2
			}
		}
		// Swap arrays for the next iteration. 
		// nextDp becomes dp (the basis for the next team count), and dp is reused as the buffer.
		dp, nextDp = nextDp, dp
	}

	fmt.Println(dp[n])
}
```