Paul hates palindromes. He assumes that string s is tolerable if each its character is one of the first p letters of the English alphabet and s doesn't contain any palindrome contiguous substring of length 2 or more.

Paul has found a tolerable string s of length n. Help him find the lexicographically next tolerable string of the same length or else state that such string does not exist.


-----Input-----

The first line contains two space-separated integers: n and p (1 ≤ n ≤ 1000; 1 ≤ p ≤ 26). The second line contains string s, consisting of n small English letters. It is guaranteed that the string is tolerable (according to the above definition).


-----Output-----

If the lexicographically next tolerable string of the same length exists, print it. Otherwise, print "NO" (without the quotes).


-----Examples-----
Input
3 3
cba

Output
NO

Input
3 4
cba

Output
cbd

Input
4 4
abcd

Output
abda



-----Note-----

String s is lexicographically larger (or simply larger) than string t with the same length, if there is number i, such that s_1 = t_1, ..., s_{i} = t_{i}, s_{i} + 1 > t_{i} + 1.

The lexicographically next tolerable string is the lexicographically minimum tolerable string which is larger than the given one.

A palindrome is a string that reads the same forward or reversed.

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: String algorithms

Greedy algorithms


Solutions:
def nextt(s):
	return chr(ord(s) + 1)
(n, k) = map(int, input().split())
s = [i for i in input()]
i = n - 1
s[i] = nextt(s[i])
while i >= 0 and i < n:
	if ord(s[i]) >= 97 + k:
		s[i] = 'a'
		i -= 1
		s[i] = nextt(s[i])
	elif i > 0 and s[i] == s[i - 1] or (i > 1 and s[i] == s[i - 2]):
		s[i] = nextt(s[i])
	else:
		i += 1
if i < 0:
	print('NO')
else:
	print(''.join(s))


import sys
(n, p) = map(int, input().split())
s = input()
a = [ord(s[i]) - ord('a') + 1 for i in range(n)]
curr = len(s) - 1
a += [p + 1, p + 1]
f = 0

def valid(x):
	nonlocal f
	if x == -1:
		return False
	if not a[x] + 1 in (a[x - 1], a[x - 2]) and a[x] + 1 <= p:
		a[x] += 1
	elif not a[x] + 2 in (a[x - 1], a[x - 2]) and a[x] + 2 <= p:
		a[x] += 2
	elif not a[x] + 3 in (a[x - 1], a[x - 2]) and a[x] + 3 <= p:
		a[x] += 3
	else:
		return True
	print(s[:x], end='')
	print(chr(a[x] + ord('a') - 1), end='')
	tmp = 1
	ind = x
	while tmp in (a[x], a[x - 1]):
		tmp += 1
	for i in range(x + 1, len(s)):
		print(chr(tmp + ord('a') - 1), end='')
		a[i] = tmp
		tmp = 1
		while tmp in (a[i], a[i - 1]):
			tmp += 1
	f = 1
	return False
while valid(curr):
	curr -= 1
if f == 1:
	return
print('NO')


import sys
(n, p) = list(map(int, sys.stdin.readline().split()))
s = sys.stdin.readline()
sl = list(s)
sl.remove('\n')
flag = 0
for i in range(n - 1, -1, -1):
	c = ord(s[i]) - 96
	prev = -1
	nprev = -1
	if c < p:
		if i - 1 >= 0:
			prev = ord(s[i - 1]) - 96
			if i - 2 >= 0:
				nprev = ord(s[i - 2]) - 96
		flag = 0
		for j in range(c + 1, p + 1):
			if j != prev and j != nprev:
				sl[i] = chr(j + 96)
				flag = 1
				break
		if flag:
			break
sn = ''.join(sl).strip()
if s.strip() == sn:
	print('NO')
else:
	sn = sn[:i + 1]
	while i < n - 1:
		for j in range(26):
			if sn[-1] != chr(j + 97):
				if i > 0 and sn[-2] != chr(j + 97):
					i += 1
					sn += chr(j + 97)
					break
				if i <= 0:
					i += 1
					sn += chr(j + 97)
					break
	print(sn)


import sys

def solve(s, k):
	l = len(s)
	for i in range(l - 1, -1, -1):
		prev = s[max(i - 2, 0):i]
		z = s[i] + 1
		while z in prev:
			z += 1
		if z >= k:
			continue
		ret = s[:i] + [z]
		while len(ret) < l:
			prev = ret[max(len(ret) - 2, 0):len(ret)]
			z = 0
			while z in prev:
				z += 1
			ret.append(z)
		return ret
	return None
(l, k) = map(int, sys.stdin.readline().split())
s = [ord(c) - ord('a') for c in sys.stdin.readline().strip()]
ans = solve(s, k)
if ans is None:
	print('NO')
else:
	print(''.join((chr(ord('a') + x) for x in ans)))


(n, p) = map(int, input().split())
(t, q) = (input(), 'NO')
if p == 2:
	if t == 'a':
		q = 'b'
	elif t == 'ab':
		q = 'ba'
elif p > 2:
	t = [ord(c) - 97 for c in t] + [27, 27]
	for k in range(n - 1, -1, -1):
		for i in range(t[k] + 1, p):
			if i - t[k - 1] and i - t[k - 2]:
				t[k] = i
				(a, b) = (min(t[k - 1], 2), min(t[k], 2))
				if a == b:
					a = 1
				t = t[:k + 1] + [3 - a - b, a, b] * (n // 3 + 1)
				print(''.join((chr(t[i] + 97) for i in range(n))))
				exit(0)
print(q)


(n, p) = map(int, input().split())
s = list(map(ord, input()))
index = n - 1
s[n - 1] += 1
p += 97
while index >= 0 and index < n:
	if s[index] >= p:
		s[index] = 97
		index -= 1
		s[index] += 1
	elif index != 0 and s[index] == s[index - 1]:
		s[index] += 1
	elif index > 1 and s[index] == s[index - 2]:
		s[index] += 1
	else:
		index += 1
if index < 0:
	print('NO')
else:
	for i in s:
		print(chr(i), end='')


import sys
inf = float('inf')

def get_array():
	return list(map(int, sys.stdin.readline().strip().split()))

def get_ints():
	return list(map(int, sys.stdin.readline().strip().split()))

def input():
	return sys.stdin.readline().strip()

def check_pallindrome(string, index):
	if index > 1:
		if string[index] != string[index - 1] and string[index] != string[index - 2]:
			return True
		else:
			return False
	elif index > 0:
		if string[index] != string[index - 1]:
			return True
		else:
			return False
	else:
		return True

def get_next(string, index, p):
	if ord(string[index]) - 96 < p:
		string[index] = chr(ord(string[index]) + 1)
		if check_pallindrome(string, index):
			return True
		else:
			return get_next(string, index, p)
	else:
		return False
(n, p) = get_ints()
string = list(input())
i = n - 1
while True:
	if i == n:
		print(''.join(string))
		break
	elif i == -1:
		print('NO')
		break
	if get_next(string, i, p):
		i += 1
	else:
		string[i] = chr(96)
		i -= 1


(n, p) = map(int, input().split())
t = [ord(c) - 97 for c in input()] + [27, 27]
for k in range(n - 1, -1, -1):
	for i in range(t[k] + 1, p):
		if i - t[k - 1] and i - t[k - 2]:
			(a, b) = (min(t[k - 1], 2), min(i, 2))
			if a == b:
				a = 1
			t = t[:k] + [i] + [3 - a - b, a, b] * (n // 3 + 1)
			print(''.join((chr(i + 97) for i in t))[:n])
			return
print('NO')


def trans(c):
	return chr(ord(c) + 1)
(n, p) = list(map(int, input().split()))
s = list(input())
s[n - 1] = trans(s[n - 1])
i = n - 1
while i >= 0 and i < n:
	if ord(s[i]) >= ord('a') + p:
		s[i] = 'a'
		i -= 1
		s[i] = trans(s[i])
	elif i > 0 and s[i] == s[i - 1] or (i > 1 and s[i] == s[i - 2]):
		s[i] = trans(s[i])
	else:
		i += 1
else:
	print('NO' if i < 0 else ''.join(s))


(n, p) = map(int, input().split())
p += ord('a') - 1
s = [*input()]
from string import ascii_lowercase
ap = [*ascii_lowercase]

def check(m):
	i = 1
	z = len(m)
	if z > 1 and m[0] == m[1]:
		return False
	while i < z - 1:
		t1 = m[i] + m[i + 1]
		t2 = m[i - 1] + m[i] + m[i + 1]
		if t1 == t1[::-1] or t2 == t2[::-1]:
			return False
		i += 1
	return True
i = n - 1
ans = 'NO'
t = s[i]
while i >= 0:
	if ord(t) == p:
		i -= 1
		t = s[i]
		continue
	t = chr(ord(t) + 1)
	m = [j for j in s]
	m[i] = t
	if check(m[:i + 1]):
		j = i + 1
		f = True
		while j < n:
			l = 97
			while l < 123:
				if j >= 2 and ord(m[j - 2]) == l or ord(m[j - 1]) == l:
					l += 1
				else:
					break
			if l == 123:
				f = False
				break
			m[j] = chr(l)
			j += 1
		m[i] = t
		if f:
			print(''.join(m))
			return
print(ans)


(n, p) = map(int, input().split())

def f(t, k):
	(a, b) = (min(t[k - 1], 2), min(t[k], 2))
	if a == b:
		a = 1
	return [3 - a - b, a, b]

def g(t, k):
	j = t[k]
	for i in range(j + 1, p):
		if i != t[k - 1] and i != t[k - 2]:
			t[k] = i
			return f(t, k)
	return None

def h(t):
	t = [ord(c) - 97 for c in t] + [27, 27]
	for k in range(n - 1, -1, -1):
		s = g(t, k)
		if s:
			d = n - k - 1
			t = t[:k + 1] + s * (d // 3) + s[:d % 3]
			return ''.join((chr(i + 97) for i in t))
	return 'NO'
t = input()
q = 'NO'
if p == 2:
	if t == 'a':
		q = 'b'
	elif t == 'ab':
		q = 'ba'
elif p > 2:
	q = h(t)
print(q)


import os
import sys
from math import *
from collections import *
from bisect import *
from io import BytesIO, IOBase

def vsInput():
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('output.txt', 'w')
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
ALPHA = 'abcdefghijklmnopqrstuvwxyz/'
M = 10 ** 9 + 7
EPS = 1e-06

def Ceil(a, b):
	return a // b + int(a % b > 0)

def value():
	return tuple(map(int, input().split()))

def array():
	return [int(i) for i in input().split()]

def Int():
	return int(input())

def Str():
	return input()

def arrayS():
	return [i for i in input().split()]
(n, p) = value()
s = list(input())[::-1]
s[0] = ALPHA[ALPHA.index(s[0]) + 1]
i = 0
while i >= 0 and i < n:
	cur = ALPHA.index(s[i])
	if cur >= p:
		s[i] = 'a'
		i += 1
		if i < n:
			s[i] = ALPHA[ALPHA.index(s[i]) + 1]
	elif i + 1 < n and s[i + 1] == s[i]:
		s[i] = ALPHA[ALPHA.index(s[i]) + 1]
	elif i + 2 < n and s[i + 2] == s[i]:
		s[i] = ALPHA[ALPHA.index(s[i]) + 1]
	else:
		i -= 1
s = s[::-1]
if s == ['a'] * n:
	print('NO')
else:
	print(*s, sep='')


import time, math as mt, bisect as bs, sys
from sys import stdin, stdout
from collections import defaultdict
from collections import deque
from fractions import Fraction
from collections import Counter
from collections import OrderedDict
pi = 3.141592653589793

def II():
	return int(stdin.readline())

def IO():
	return stdin.readline()

def IP():
	return map(int, stdin.readline().split())

def L():
	return list(map(int, stdin.readline().split()))

def P(x):
	return stdout.write(str(x) + '\n')

def PI(x, y):
	return stdout.write(str(x) + ' ' + str(y) + '\n')

def lcm(a, b):
	return a * b // gcd(a, b)

def gcd(a, b):
	if a == 0:
		return b
	elif b == 0:
		return a
	if a > b:
		return gcd(a % b, b)
	else:
		return gcd(a, b % a)

def readTree():
	v = int(input())
	adj = [set() for i in range(v + 1)]
	for i in range(v - 1):
		(u1, u2) = In()
		adj[u1].add(u2)
		adj[u2].add(u1)
	return (adj, v)

def bfs(adj, v):
	visited = [False] * (v + 1)
	q = deque()
	while q:
		pass

def sieve():
	li = [True] * 1000001
	(li[0], li[1]) = (False, False)
	for i in range(2, len(li), 1):
		if li[i] == True:
			for j in range(i * i, len(li), i):
				li[j] = False
	prime = []
	for i in range(1000001):
		if li[i] == True:
			prime.append(i)
	return prime

def setBit(n):
	count = 0
	while n != 0:
		n = n & n - 1
		count += 1
	return count
mx = 10 ** 7
spf = [mx] * (mx + 1)

def SPF():
	spf[1] = 1
	for i in range(2, mx + 1):
		if spf[i] == mx:
			spf[i] = i
			for j in range(i * i, mx + 1, i):
				if i < spf[j]:
					spf[j] = i
	return
mod = 10 ** 9 + 7

def solve():
	(n, p) = IP()
	s = input()
	cpy = p
	p = ord('a') + p
	brk = False
	fnd = False
	new = ''
	for i in range(n - 1, -1, -1):
		for j in range(ord(s[i]) + 1, p):
			c = chr(j)
			(y, z) = (max(0, i - 1), max(0, i - 2))
			if c != s[y] and c != s[z]:
				new = s[:i] + c
				left = n - i - 1
				last = i + 1
				brk = True
				fnd = True
				break
		if brk:
			break
	if not fnd:
		P('NO')
		return
	for i in range(left):
		for j in range(cpy):
			c = chr(ord('a') + j)
			(y, z) = (max(0, last - 1), max(0, last - 2))
			if c != new[y] and c != new[z]:
				new += c
				last += 1
				break
	if len(new) == len(s):
		P(new)
		return
	else:
		P('NO')
		return
t = 1
for i in range(t):
	solve()


import sys
import math as mt
import bisect
t = 1
for __ in range(t):
	(n, p) = map(int, input().split())
	up = chr(p + 96)
	s = input()
	ind = -1
	for i in range(len(s) - 1, -1, -1):
		if i >= 2:
			for j in range(26):
				if chr(97 + j) > s[i] and chr(97 + j) <= up and (chr(97 + j) != s[i - 1]) and (chr(97 + j) != s[i - 2]):
					ind = i
					ch = chr(97 + j)
					break
		elif i == 1:
			for j in range(26):
				if chr(97 + j) > s[i] and chr(97 + j) <= up and (chr(97 + j) != s[i - 1]):
					ind = i
					ch = chr(97 + j)
					break
		else:
			for j in range(26):
				if chr(97 + j) > s[i] and chr(97 + j) <= up:
					ind = i
					ch = chr(97 + j)
					break
		if ind != -1:
			break
	if ind == -1:
		print('NO')
	else:
		s1 = s[:ind]
		s1 += ch
		falg = True
		for j in range(ind + 1, len(s)):
			ch2 = 0
			for j1 in range(26):
				if len(s1) <= 1:
					if chr(j1 + 97) != s1[-1] and chr(j1 + 97) <= up:
						s1 += chr(j1 + 97)
						ch2 = 1
						break
				elif chr(j1 + 97) != s1[-1] and chr(j1 + 97) != s1[-2] and (chr(j1 + 97) <= up):
					ch2 = 1
					s1 += chr(j1 + 97)
					break
				if ch2 == 1:
					break
			if ch2 == 0:
				falg = False
		if falg == True:
			print(s1)
		else:
			print('NO')


def main():
	(n, p) = map(int, input().split())
	l = [p, p] + [ord(c) - 97 for c in input()]
	a = l[-2]
	for i in range(n + 1, 1, -1):
		(a, b) = (l[i - 2], a)
		for x in range(l[i] + 1, p):
			if a != x != b:
				l[i] = x
				break
		else:
			continue
		break
	else:
		print('NO')
		return
	(a, b) = (l[i - 1], x)
	for i in range(i + 1, n + 2):
		for x in range(p):
			if a != x != b:
				l[i] = x
				(a, b) = (b, x)
				break
	print(''.join((chr(x + 97) for x in l[2:])))
main()


(n, p) = map(int, input().split())
s = ['#'] + list(input()) + ['#']
s1 = s[:]
aa = 'abcdefghijklmnopqrstuvwxyz'
ind = 0
for i in range(n, 0, -1):
	ind = aa.index(s[i]) + 1
	c = 0
	ans = 0
	while ind < p:
		if aa[ind] != s[i - 1] and aa[ind] != s[i - 2]:
			c = 1
			ans = ind
			break
		ind += 1
	if c:
		s[i] = aa[ans]
		ind = i
		break
ans = 0
p = 3
for i in range(ind + 1, n + 1):
	ans = 0
	while aa[ans % p] == s[i - 2] or aa[ans % p] == s[i - 1]:
		ans += 1
	s[i] = aa[ans % p]
if s <= s1:
	print('NO')
	exit()
print(''.join(s[1:-1]))


def solve(s, n):
	if len(s) == 1:
		return chr(ord(s[0]) + 1) if ord(s[0]) + 1 < ord('a') + n else 'NO'
	for i in reversed(range(2, len(s))):
		c = s[i]
		for j in range(ord(c) + 1, ord('a') + n):
			next = chr(j)
			if next != s[i - 1] and next != s[i - 2]:
				new_s = s[0:i] + next
				new_s = fill(new_s, n, s, i)
				return new_s
	for i in range(ord(s[1]) + 1, ord('a') + n):
		next = chr(i)
		if next != s[0]:
			new_s = s[0] + next
			new_s = fill(new_s, n, s, 1)
			return new_s
	for i in range(ord(s[0]) + 1, ord('a') + n):
		next = chr(i)
		new_s = next
		new_s = fill(new_s, n, s, 0)
		return new_s
	return 'NO'

def fill(new_s, n, s, i):
	res = ['a', 'b', 'c']
	for x in range(i + 1, len(s)):
		for y in res:
			if ord(y) < ord('a') + n and y != new_s[-1] and (len(new_s) < 2 or y != new_s[-2]):
				new_s += y
				break
	return new_s if len(new_s) == len(s) else 'NO'
(m, n) = list(map(int, input().split()))
s = input()
print(solve(s, n))


(n, p) = list(map(int, input().split()))
s = input()
slist = list(s)
bad = False
if p == 1:
	print('NO')
	bad = True
if p == 2:
	if s == 'a':
		print('b')
	elif s == 'ab':
		print('ba')
	else:
		print('NO')
	bad = True

def is_palindrome(a):
	if len(a) == 1:
		return False
	return a == list(reversed(a))

def _gen_banned(c, with_c=True):
	nonlocal slist
	banned = []
	if c - 2 >= 0:
		banned.append(ord(slist[c - 2]))
	if c - 1 >= 0:
		banned.append(ord(slist[c - 1]))
	if with_c:
		banned.append(ord(slist[c]))
	return banned
if not bad:
	for c in range(n - 1, -1, -1):
		banned = _gen_banned(c)
		if sorted(banned) == [96 + p - 2, 96 + p - 1, 96 + p]:
			continue
		else:
			for i in range(ord(slist[c]) + 1, 96 + p + 1):
				if i not in banned:
					slist[c] = chr(i)
					break
			if slist[c] == s[c]:
				continue
			j = c + 1
			while j < n:
				banned = _gen_banned(j, with_c=False)
				for i in range(97, 96 + p + 1):
					if i not in banned:
						slist[j] = chr(i)
						break
				j += 1
			print(''.join(slist))
			break
	if ''.join(slist) == s:
		print('NO')


from __future__ import division, print_function
import os
import sys
from io import BytesIO, IOBase

def main():

	def getAvailableStart():
		for i in range(n - 1, -1, -1):
			originalCharId = ord(string[i]) - 97
			for charId in range(originalCharId + 1, p):
				newChar = chr(charId + 97)
				if i == 0:
					return (i, newChar)
				if i >= 1:
					if newChar == string[i - 1]:
						continue
				if i >= 2:
					if newChar == string[i - 2]:
						continue
				return (i, newChar)
		return (-1, '')
	(n, p) = [int(x) for x in input().split()]
	string = input()
	if n <= 3 and p < n or (n > 3 and p < 3):
		print('NO')
		return
	(start, newChar) = getAvailableStart()
	if ~start:
		stringAsArray = [char for char in string]
		stringAsArray[start] = newChar
		bestChars = ['a', 'b', 'c']
		for i in range(start + 1, n):
			for char in bestChars:
				if i >= 1:
					if char == stringAsArray[i - 1]:
						continue
				if i >= 2:
					if char == stringAsArray[i - 2]:
						continue
				break
			stringAsArray[i] = char
		print(''.join(stringAsArray))
	else:
		print('NO')
BUFFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
input = lambda : sys.stdin.readline().rstrip('\r\n')

def print(*args, **kwargs):
	sep = kwargs.pop('sep', ' ')
	file = kwargs.pop('file', sys.stdout)
	atStart = True
	for x in args:
		if not atStart:
			file.write(sep)
		file.write(str(x))
		atStart = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
main()


import sys

def main():
	fin = sys.stdin
	fout = sys.stdout
	L = list('abcdefghijklmnopqrstuvwxyz')
	(n, p) = map(int, fin.readline().split())
	A = list(fin.readline())
	for i in range(n - 1, 1, -1):
		pr = ord(A[i - 1]) - ord('a')
		pp = ord(A[i - 2]) - ord('a')
		cur = ord(A[i]) - ord('a') + 1
		while cur < p and (cur == pr or cur == pp):
			cur += 1
		if cur < p:
			A[i] = chr(cur + ord('a'))
			print(''.join(A[:i]), end='')
			print(chr(cur + ord('a')), end='')
			for j in range(i + 1, n):
				pr = ord(A[j - 1]) - ord('a')
				pp = ord(A[j - 2]) - ord('a')
				cur = 0
				while cur < p and (cur == pr or cur == pp):
					cur += 1
				print(chr(cur + ord('a')), end='')
				A[j] = chr(cur + ord('a'))
			return
	if n >= 2:
		i = 1
		pr = ord(A[i - 1]) - ord('a')
		pp = -1
		cur = ord(A[i]) - ord('a') + 1
		while cur < p and (cur == pr or cur == pp):
			cur += 1
		if cur < p:
			A[i] = chr(cur + ord('a'))
			print(''.join(A[:i]), end='')
			print(chr(cur + ord('a')), end='')
			for j in range(i + 1, n):
				pr = ord(A[j - 1]) - ord('a')
				pp = ord(A[j - 2]) - ord('a')
				cur = 0
				while cur < p and (cur == pr or cur == pp):
					cur += 1
				print(chr(cur + ord('a')), end='')
				A[j] = chr(cur + ord('a'))
			return
	i = 0
	pr = pp = -1
	cur = ord(A[i]) - ord('a') + 1
	while cur < p and (cur == pr or cur == pp):
		cur += 1
	if cur < p:
		A[i] = chr(cur + ord('a'))
		print(chr(cur + ord('a')), end='')
		if n == 1:
			return
		j = 1
		pr = ord(A[j - 1]) - ord('a')
		pp = -1
		cur = 0
		while cur < p and (cur == pr or cur == pp):
			cur += 1
		print(chr(cur + ord('a')), end='')
		A[j] = chr(cur + ord('a'))
		for j in range(i + 2, n):
			pr = ord(A[j - 1]) - ord('a')
			pp = ord(A[j - 2]) - ord('a')
			cur = 0
			while cur < p and (cur == pr or cur == pp):
				cur += 1
			print(chr(cur + ord('a')), end='')
			A[j] = chr(cur + ord('a'))
		return
	print('NO')
	fin.close()
	fout.close()
main()


def clean(n, w, i):
	for j in range(i + 1, n):
		if 0 not in [w[j - 1], w[j - 2]]:
			w[j] = 0
		elif 1 not in [w[j - 1], w[j - 2]]:
			w[j] = 1
		else:
			w[j] = 2
	return ''.join([chr(ord('a') + x) for x in w])

def solve():
	(n, p) = map(int, input().split())
	w = [ord(c) - ord('a') for c in input()]
	if p == 1:
		return 'NO'
	elif p == 2:
		if n == 1 and w[0] == 0:
			return 'b'
		elif n == 2 and w[0] == 0:
			return 'ba'
		else:
			return 'NO'
	elif n == 1:
		if w[0] == p - 1:
			return 'NO'
		else:
			return chr(ord('a') + w[0] + 1)
	for i in range(n - 1, 1, -1):
		for k in range(1, 3 + 1):
			if w[i] + k not in [w[i - 1], w[i - 2]] and w[i] + k < p:
				w[i] += k
				return clean(n, w, i)
	for k in range(1, 2 + 1):
		if w[1] + k not in [w[0]] and w[1] + k < p:
			w[1] += k
			return clean(n, w, 1)
	if w[0] + 1 < p:
		w[0] += 1
		w[1] = 0
		return clean(n, w, 1)
	return 'NO'
print(solve())


(n, p) = map(int, input().split())
s = list((ord(i) - 97 for i in input()))
for i in range(n - 1, -1, -1):
	for j in range(s[i] + 1, p):
		if (i < 1 or j != s[i - 1]) and (i < 2 or j != s[i - 2]):
			s[i] = j
			for i in range(i + 1, n):
				for j in range(p):
					if (i < 1 or j != s[i - 1]) and (i < 2 or j != s[i - 2]):
						s[i] = j
						break
			print(''.join((chr(i + 97) for i in s)))
			return
print('NO')


def palin(a):
	a = a - 1
	m = len(c) - 1
	if a >= 0:
		if c[a] == c[a + 2]:
			return 1
	return 0

def inc(i):
	if len(c) == 1:
		if ord(c[i]) - 96 == b:
			print('NO')
			exit()
		else:
			c[i] = chr(ord(c[i]) + 1)
			return 0
	if ord(c[i]) - 96 == b:
		c[i] = 'a'
		if i == 1:
			if c[0] == chr(96 + b):
				print('NO')
				exit()
		inc(i - 1)
		if c[i] == c[i - 1] or palin(i - 1):
			inc(i)
	else:
		c[i] = chr(ord(c[i]) + 1)
		if c[i] == c[i - 1] or palin(i - 1):
			inc(i)
(a, b) = map(int, input().split(' '))
c = list(input())
e = 1
i = a - 1
inc(i)
print(''.join(c))


(n, k) = map(int, input().split())
s = input()
if k == 1 and n > 1:
	print('NO')
	exit(0)
if k <= 2:
	if n > 2:
		print('NO')
		exit(0)
arr = []
for ch in s:
	arr.append(ord(ch) - 96)
i = n - 1
last = -1
while i >= 0:
	for num in range(arr[i] + 1, k + 1):
		if i - 2 >= 0 and num != arr[i - 1] and (num != arr[i - 2]):
			arr[i] = num
			last = i
			break
		elif i - 2 < 0 and i - 1 == 0 and (arr[i - 1] != num):
			arr[i] = num
			last = i
			break
		elif i == 0:
			arr[i] = num
			last = i
			break
	if last != -1:
		break
	i -= 1
if i < 0:
	print('NO')
	exit(0)
for i in range(i + 1, n):
	for num in range(1, k + 1):
		if i - 2 >= 0 and num != arr[i - 1] and (num != arr[i - 2]):
			arr[i] = num
			break
		elif i - 2 < 0 and i - 1 == 0 and (arr[i - 1] != num):
			arr[i] = num
			break
ans = ''
for num in arr:
	ans += chr(num + 96)
print(ans)


import math
import sys
input = sys.stdin.readline

def inp():
	return int(input())

def inlt():
	return list(map(int, input().split()))

def insr():
	s = input().strip()
	return list(s[:len(s)])

def invr():
	return map(int, input().split())
(n, p) = invr()
s = insr()
s[n - 1] = chr(ord(s[n - 1]) + 1)
i = n - 1
while i >= 0 and i < n:
	if ord(s[i]) >= ord('a') + p:
		s[i] = 'a'
		s[i - 1] = chr(ord(s[i - 1]) + 1)
		i -= 1
	elif i > 0 and s[i] == s[i - 1] or (i > 1 and s[i] == s[i - 2]):
		s[i] = chr(ord(s[i]) + 1)
	else:
		i += 1
if i > 0:
	print(''.join(s))
else:
	print('NO')


import sys
from functools import lru_cache, cmp_to_key
from heapq import merge, heapify, heappop, heappush
from math import *
from collections import defaultdict as dd, deque, Counter as C
from itertools import combinations as comb, permutations as perm
from bisect import bisect_left as bl, bisect_right as br, bisect
from time import perf_counter
from fractions import Fraction
import copy
import time
starttime = time.time()
mod = int(pow(10, 9) + 7)
mod2 = 998244353

def data():
	return sys.stdin.readline().strip()

def out(*var, end='\n'):
	sys.stdout.write(' '.join(map(str, var)) + end)

def L():
	return list(sp())

def sl():
	return list(ssp())

def sp():
	return map(int, data().split())

def ssp():
	return map(str, data().split())

def l1d(n, val=0):
	return [val for i in range(n)]

def l2d(n, m, val=0):
	return [l1d(n, val) for j in range(m)]
try:
	sys.stdin = open('input.txt', 'r')
except:
	pass

def pmat(A):
	for ele in A:
		print(*ele, end='\n')
(n, p) = list(map(int, input().split()))
s = list(input())
s[n - 1] = chr(ord(s[n - 1]) + 1)
i = n - 1
while i >= 0 and i < n:
	if ord(s[i]) >= ord('a') + p:
		s[i] = 'a'
		i -= 1
		s[i] = chr(ord(s[i]) + 1)
	elif i > 0 and s[i] == s[i - 1] or (i > 1 and s[i] == s[i - 2]):
		s[i] = chr(ord(s[i]) + 1)
	else:
		i += 1
print('NO' if i < 0 else ''.join(s))
endtime = time.time()


from sys import stdin, setrecursionlimit
import heapq
(n, p) = list(map(int, stdin.readline().split()))
string = list(stdin.readline().strip())
i = n - 1

def check_pallindrome(string, index):
	if index > 1:
		if string[index - 1] != string[index] and string[index - 2] != string[index]:
			return True
		else:
			return False
	elif index > 0:
		if string[index - 1] != string[index]:
			return True
		else:
			return False
	else:
		return True

def get_next(string, index, p):
	if ord(string[index]) - 96 < p:
		string[index] = chr(ord(string[i]) + 1)
		if check_pallindrome(string, index):
			return True
		else:
			return get_next(string, index, p)
	else:
		return False
while True:
	if i == n:
		print(''.join(string))
		break
	if i == -1:
		print('NO')
		break
	if get_next(string, i, p):
		i += 1
	else:
		string[i] = chr(96)
		i -= 1


import sys
from math import log2, floor, ceil, sqrt, gcd
import bisect
Ri = lambda : [int(x) for x in sys.stdin.readline().split()]
ri = lambda : sys.stdin.readline().strip()

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
INF = 10 ** 18
MOD = 1000000007
(n, k) = Ri()
st = ri()
st = [i for i in st]
arr = [chr(ord('a') + i) for i in range(k)]
flag = -1
ch = -1
if n == 1:
	if st[0] == arr[-1]:
		NO()
	else:
		print(chr(ord(st[0]) + 1))
else:
	for i in range(n - 1, -1, -1):
		for j in range(ord(st[i]) - ord('a') + 1, k):
			tch = arr[j]
			if i - 2 >= 0:
				if tch == st[i - 1] or tch == st[i - 2]:
					continue
				else:
					flag = i
					ch = tch
					break
			elif i - 1 >= 0:
				if tch == st[i - 1]:
					continue
				else:
					flag = i
					ch = tch
					break
			else:
				flag = i
				ch = tch
				break
		if flag != -1:
			break
	if flag == -1:
		NO()
	else:
		st[flag] = ch
		for i in range(flag + 1, n):
			for j in range(0, k):
				tch = arr[j]
				if i - 2 >= 0:
					if tch == st[i - 1] or tch == st[i - 2]:
						continue
					else:
						flag = i
						ch = tch
						st[i] = ch
						break
				elif i - 1 >= 0:
					if tch == st[i - 1]:
						continue
					else:
						flag = i
						ch = tch
						st[i] = ch
						break
				else:
					flag = i
					ch = tch
					st[i] = ch
					break
		print(''.join(st))