← Home
package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Buffer(make([]byte, 1024*1024), 1024*1024)
	scanner.Scan()
	nStr := scanner.Text()
	n, err := strconv.Atoi(nStr)
	if err != nil || n == 0 {
		return
	}
	scanner.Scan()
	s := scanner.Text()

	var M1 int64 = 1000000007
	var M2 int64 = 1000000009
	var B1 int64 = 313
	var B2 int64 = 317

	P1 := make([]int64, n+1)
	P2 := make([]int64, n+1)
	P1[0] = 1
	P2[0] = 1
	for i := 1; i <= n; i++ {
		P1[i] = P1[i-1] * B1 % M1
		P2[i] = P2[i-1] * B2 % M2
	}

	H1 := make([]int64, n+1)
	H2 := make([]int64, n+1)
	HR1 := make([]int64, n+1)
	HR2 := make([]int64, n+1)

	for i := 1; i <= n; i++ {
		H1[i] = (H1[i-1]*B1 + int64(s[i-1])) % M1
		H2[i] = (H2[i-1]*B2 + int64(s[i-1])) % M2

		HR1[i] = (HR1[i-1]*B1 + int64(s[n-i])) % M1
		HR2[i] = (HR2[i-1]*B2 + int64(s[n-i])) % M2
	}

	getHash := func(L, R int) (int64, int64) {
		if L > R {
			return 0, 0
		}
		length := R - L + 1
		h1 := (H1[R+1] - H1[L]*P1[length]) % M1
		if h1 < 0 {
			h1 += M1
		}
		h2 := (H2[R+1] - H2[L]*P2[length]) % M2
		if h2 < 0 {
			h2 += M2
		}
		return h1, h2
	}

	getHashRev := func(L, R int) (int64, int64) {
		if L > R {
			return 0, 0
		}
		Lrev := n - 1 - R
		Rrev := n - 1 - L
		length := Rrev - Lrev + 1
		h1 := (HR1[Rrev+1] - HR1[Lrev]*P1[length]) % M1
		if h1 < 0 {
			h1 += M1
		}
		h2 := (HR2[Rrev+1] - HR2[Lrev]*P2[length]) % M2
		if h2 < 0 {
			h2 += M2
		}
		return h1, h2
	}

	getLCP := func(L, R int) int {
		low := 0
		high := L
		if n-1-R < high {
			high = n - 1 - R
		}
		ans := 0
		for low <= high {
			mid := (low + high) / 2
			if mid == 0 {
				ans = 0
				low = mid + 1
				continue
			}
			h1, h2 := getHash(R+1, R+mid)
			hr1, hr2 := getHashRev(L-mid, L-1)
			if h1 == hr1 && h2 == hr2 {
				ans = mid
				low = mid + 1
			} else {
				high = mid - 1
			}
		}
		return ans
	}

	T := make([]byte, 2*n+1)
	for i := 0; i < n; i++ {
		T[2*i] = '#'
		T[2*i+1] = s[i]
	}
	T[2*n] = '#'

	P := make([]int, 2*n+1)
	C, R_man := 0, 0
	for i := 0; i < 2*n+1; i++ {
		iMirror := 2*C - i
		if R_man > i {
			if R_man-i < P[iMirror] {
				P[i] = R_man - i
			} else {
				P[i] = P[iMirror]
			}
		} else {
			P[i] = 0
		}
		for i-1-P[i] >= 0 && i+1+P[i] < 2*n+1 && T[i-1-P[i]] == T[i+1+P[i]] {
			P[i]++
		}
		if i+P[i] > R_man {
			C = i
			R_man = i + P[i]
		}
	}

	radOdd := make([]int, n)
	for i := 0; i < n; i++ {
		radOdd[i] = (P[2*i+1] + 1) / 2
	}
	radEven := make([]int, n-1)
	for i := 0; i < n-1; i++ {
		radEven[i] = P[2*i+2] / 2
	}

	D2 := make([]int, n+5)
	for i := 0; i < n; i++ {
		r := radOdd[i]
		if r > 0 {
			idx := i - r + 1
			if idx < 0 {
				idx = 0
			}
			D2[idx] += 1
			D2[i+1] -= 2
			D2[i+r+1] += 1
		}
	}

	for i := 0; i < n-1; i++ {
		r := radEven[i]
		if r > 0 {
			idx := i - r + 1
			if idx < 0 {
				idx = 0
			}
			D2[idx] += 1
			D2[i+1] -= 1
			D2[i+2] -= 1
			D2[i+r+2] += 1
		}
	}

	cover := make([]int, n)
	curD1 := 0
	curV := 0
	for i := 0; i < n; i++ {
		curD1 += D2[i]
		curV += curD1
		cover[i] = curV
	}

	loss := make([]int, n)
	for i := 0; i < n; i++ {
		loss[i] = cover[i] - radOdd[i]
	}

	gain := make([][26]int, n)
	for i := 0; i < n; i++ {
		r := radOdd[i]
		L := i - r
		R := i + r
		if L >= 0 && R < n {
			r2 := getLCP(L, R)
			g := r2 + 1
			gain[L][s[R]-'a'] += g
			gain[R][s[L]-'a'] += g
		}
	}

	for i := 0; i < n-1; i++ {
		r := radEven[i]
		L := i - r
		R := i + 1 + r
		if L >= 0 && R < n {
			r2 := getLCP(L, R)
			g := r2 + 1
			gain[L][s[R]-'a'] += g
			gain[R][s[L]-'a'] += g
		}
	}

	initialPalindromes := int64(0)
	for i := 0; i < n; i++ {
		initialPalindromes += int64(radOdd[i])
	}
	for i := 0; i < n-1; i++ {
		initialPalindromes += int64(radEven[i])
	}

	maxPalindromes := initialPalindromes
	best_i := n
	best_c := byte(0)

	isSmaller := func(i1 int, c1 byte, i2 int, c2 byte) bool {
		if i1 == i2 {
			return c1 < c2
		}
		if i1 < i2 {
			return c1 < s[i1]
		}
		return s[i2] < c2
	}

	for i := 0; i < n; i++ {
		for c := 0; c < 26; c++ {
			charC := byte('a' + c)
			if charC == s[i] {
				continue
			}

			currentPals := initialPalindromes + int64(gain[i][c]) - int64(loss[i])

			if currentPals > maxPalindromes {
				maxPalindromes = currentPals
				best_i = i
				best_c = charC
			} else if currentPals == maxPalindromes {
				if isSmaller(i, charC, best_i, best_c) {
					best_i = i
					best_c = charC
				}
			}
		}
	}

	var res []byte
	if best_i == n {
		res = []byte(s)
	} else {
		res = []byte(s)
		res[best_i] = best_c
	}

	fmt.Println(maxPalindromes)
	fmt.Println(string(res))
}