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))
}