CodeEff/ECCO huggingface dataset:
# Original solution
N = int(eval(input()))
S = input().strip()
cmax = 0
for n in range(1,N-1):
    X = S[:n]
    Y = S[n:]
    Cx = {}
    Cy = {}
    for i in range(n):
        a = X[i]
        if a not in Cx:
            Cx[a] = 0
        Cx[a] += 1
    for i in range(N-n):
        a = Y[i]
        if a not in Cy:
            Cy[a]=0
        Cy[a] += 1
    cnt = 0
    for a in Cx:
        if a in Cy:
            cnt += 1
    cmax = max(cmax,cnt)
print(cmax)

# Optimized solution
N = int(eval(input()))
S = input().strip()
cmax = 0
for i in range(1,N-1):
    X = set(list(S[:i]))
    Y = set(list(S[i:]))
    Z = X&Y
    cmax = max(cmax,len(Z))
print(cmax)
# Original solution
# code-festival-2016-qualaC - 次のアルファベット / Next Letter
from string import ascii_lowercase as abc


def main():
    S = input().rstrip()
    K = int(input())
    N, MOD = len(S), 26
    # dist[c] := distance to "a" through "z"
    dist = {c: 26 - i for i, c in enumerate(abc)}
    dist["a"] = 0
    A = [dist[i] for i in S]
    for i in range(N):
        if A[i] and A[i] <= K:  # A[i] -> "a" if possible
            A[i], K = 0, K - A[i]
    A[-1] = (A[-1] - K) % MOD  # use the remaining K on A[-1]
    rest = {v: k for k, v in dist.items()}
    ans = [rest[i] for i in A]  # restore dist to chr
    print(*ans, sep="")


if __name__ == "__main__":
    main()


# Optimized solution
# code-festival-2016-qualaC - 次のアルファベット / Next Letter
from string import ascii_lowercase as abc


def main():
    S = input().rstrip()
    K = int(eval(input()))
    # dist[c] := distance to "a" through "z"
    dist = {c: 26 - i for i, c in enumerate(abc)}
    dist["a"] = 0
    A = [dist[i] for i in S]
    ans = ""
    for i, s in zip(A[:-1], S[:-1]):
        if 0 < i <= K:  # change s to "a" if possible
            ans += "a"
            K -= i
        else:
            ans += s
    # use the remaining K on A[-1] and combine with ans
    ans += chr((ord(S[-1]) + K - ord("a")) % 26 + ord("a"))
    print(ans)


if __name__ == "__main__":
    main()
# Original solution
# code-festival-2016-qualaC - 次のアルファベット / Next Letter
from string import ascii_lowercase as abc


def main():
    S = input().rstrip()
    K = int(eval(input()))
    # dist[c] := distance to "a" through "z"
    dist = {c: 26 - i for i, c in enumerate(abc)}
    dist["a"] = 0
    A = [dist[i] for i in S]
    ans = ""
    for i, s in zip(A[:-1], S[:-1]):
        if 0 < i <= K:  # change s to "a" if possible
            ans += "a"
            K -= i
        else:
            ans += s
    # use the remaining K on A[-1] and combine with ans
    ans += chr((ord(S[-1]) + K - ord("a")) % 26 + ord("a"))
    print(ans)


if __name__ == "__main__":
    main()

# Optimized solution
# code-festival-2016-qualaC - 次のアルファベット / Next Letter
def main():
    S = input().rstrip()
    K = int(eval(input()))
    abc = "abcdefghijklmnopqrstuvwxyz"
    # dist[c] := distance to "a" through "z"
    dist = {c: 26 - i for i, c in enumerate(abc)}
    dist["a"] = 0
    A = [dist[i] for i in S]
    ans = ""
    for i, s in zip(A[:-1], S[:-1]):
        if 0 < i <= K:  # change s to "a" if possible
            ans += "a"
            K -= i
        else:
            ans += s
    # use the remaining K on A[-1] and combine with ans
    ans += chr((ord(S[-1]) + K - ord("a")) % 26 + ord("a"))
    print(ans)


if __name__ == "__main__":
    main()
# Original solution
s, k = input(), int(input())

ans = []
a = ord('z') + 1
for i in s:
    if k == 0:
        ans.append(ord(i))
    elif a - ord(i) <= k and i != 'a':
        k -= a - ord(i)
        ans.append(ord('a'))
    else:
        ans.append(ord(i))
ans[-1] += k % 26
if ans[-1] >= a:
    ans[-1] -= 26
print(*map(chr, ans), sep='')


# Optimized solution
s, k = input(), int(input())

ans = []
a = ord('z') + 1
for i in s:
    if a - ord(i) <= k and i != 'a':
        k -= a - ord(i)
        ans.append(ord('a'))
    else:
        ans.append(ord(i))
ans[-1] += k % 26
if ans[-1] >= a:
    ans[-1] -= 26
print(*map(chr, ans), sep='')
# Original solution
s = input()
K = eval(input())

alpha = [chr(i) for i in range(97,97+26)]

for moji in range(len(s)):
	if alpha.index(s[moji]) != 0:
		if K >= 26-alpha.index(s[moji]):
			K = K - (26-alpha.index(s[moji]))
			s = s[:moji] + 'a' + s[moji+1:] 

if K>0:
	last_char = alpha[ alpha.index(s[-1]) + (K % 26) ]
	s = s[:-1] + last_char

print(s)

# Optimized solution
s = input()
K = eval(input())

alpha = [chr(i) for i in range(97,97+26)]

i = 0
while K>=26 and i<len(s)-1:
	if alpha.index(s[i]) != 0:
		K = K - (26 - alpha.index(s[i]))
		s = s[:i] + 'a' + s[i+1:]
	i=i+1

for moji in range(i, len(s)):
	if alpha.index(s[moji]) != 0:
		if K >= 26-alpha.index(s[moji]):
			K = K - (26-alpha.index(s[moji]))
			s = s[:moji] + 'a' + s[moji+1:] 

if K>0:
	last_char = alpha[ alpha.index(s[-1]) + (K % 26) ]
	s = s[:-1] + last_char

print(s)
# Original solution
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list([int(x)-1 for x in input().split()])
def II(): return int(eval(input()))
def IF(): return float(eval(input()))
def S(): return input().rstrip()
def LS(): return S().split()
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = 1e10

#solve
def solve():
    s = S()
    k = II()
    ans = ""
    for si in s[:-1]:
        x = (ord("a") - ord(si)) % 26
        if x <= k:
            k -= x
            ans += "a"
        else:
            ans += si
    ans += chr(ord("a") + (k - (ord("a") - ord(s[-1])) % 26) % 26)
    print(ans)
    return


#main
if __name__ == '__main__':
    solve()


# Optimized solution
#!/usr/bin/env python3
from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list([int(x)-1 for x in input().split()])
def II(): return int(eval(input()))
def IF(): return float(eval(input()))
def S(): return input().rstrip()
def LS(): return S().split()
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = 1e10

#solve
def solve():
    s = S()
    k = II()
    ans = []
    for si in s[:-1]:
        x = (ord("a") - ord(si)) % 26
        if x <= k:
            k -= x
            ans.append("a")
        else:
            ans.append(si)
    ans.append(chr(ord("a") + (k - (ord("a") - ord(s[-1])) % 26) % 26))
    print(("".join(ans)))
    return


#main
if __name__ == '__main__':
    solve()
# Original solution
import sys
input = sys.stdin.readline
from operator import itemgetter
sys.setrecursionlimit(10000000)
INF = 10**30

def main():
    s = input().strip()
    k = int(input().strip())
    ans = ""
    for i, c in enumerate(s):
        if i == len(s)-1:
            ans += chr(ord('a') + (ord(c) + k % 26 - ord('a')) % 26)
            break
        d = ord('z') - ord(c) + 1
        if d < k:
            k -= d
            ans += 'a'
        else:
            ans += c
    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
import sys
input = sys.stdin.readline
from operator import itemgetter
sys.setrecursionlimit(10000000)
INF = 10**30

def main():
    s = input().strip()
    ans = list(s[:])
    k = int(input().strip())
    for i in range(len(s)):
        d = (ord('z') - ord(s[i]) + 1) % 26
        if k - d >= 0:
            ans[i] = 'a'
            k -= d
        if i == len(s) - 1:
            # print((ord(ans[i]) + k%26) % 26)
            ans[i] = chr(ord('a') + (ord(ans[i]) - ord('a') + k%26) % 26)
    print((''.join(ans)))

if __name__ == '__main__':
    main()
# Original solution
# -*- coding: utf-8 -*-
import sys,copy,math,heapq,itertools as it,fractions,re,bisect,collections as coll

alpha = "abcdefghijklmnopqrstuvwxyz"

s = input()
K = int(input())
dic = dict([alpha[i], i] for i in range(len(alpha)))

ans = [] 
for si in s:
    d = 26 - dic[si] if si != "a" else 0
    if d <= K:
        ans.append("a")
        K -= d
    else:
        ans.append(si)

if K > 0:
    ans[-1] = alpha[(dic[ans[-1]] + K) % 26]

print("".join(ans))


# Optimized solution
s = list(input())
K = int(input())
for i in range(len(s)):
  if s[i] == 'a': continue
  d = ord('z') - ord(s[i]) + 1
  if K >= d:
    s[i] = 'a'
    K -= d
    
K %= 26
s[-1] = chr((ord(s[-1]) - ord('a') + K)%26 + ord('a'))
  
print("".join(s))
# Original solution
s = input()
k = eval(input())

def solve(s, k, i):
    if i >= len(s):
        # print "over"
        return s
    if i == len(s)-1:
        # print "equal"
        t = ord(s[i])+k
        if t > ord("z"):
            # n = (ord("z") - ord("a") + 1)/(t - ord("z"))
            # t = t - (ord("z")-ord("a"))*n
            while t > ord("z"):
                t -= (ord("z") - ord("a") + 1)
        s = s[:i] + chr(t)
        # print s, k
    elif ord(s[i]) + k > ord("z"):
        # print "carry"
        k = k - ord("z") + ord(s[i]) -1
        s = s[:i] + "a" + s[i+1:]        
        # print s,k
    return solve(s,k,i+1)
    
print(solve(s,k,0))

# Optimized solution
s = input()
k = eval(input())
i = 0
while True:
    if i == len(s)-1:
        # print "equal"
        t = ord(s[i])+k
        if t > ord("z"):
            t -= ord("a")
            t %= (ord("z")-ord("a") + 1)
            t += ord("a")
        s = s[:i] + chr(t)
        print(s)
        exit()
        # print s, k
    elif s[i] != "a" and ord(s[i]) + k > ord("z"):
        # print "carry"
        k = k - ord("z") + ord(s[i]) -1
        s = s[:i] + "a" + s[i+1:]        
        # print s,k
    i += 1
# Original solution
import sys
from functools import lru_cache

sys.setrecursionlimit(10 ** 8)


@lru_cache(None)
def dp(i, prev):
    if i == N:
        return 0
    else:
        if prev is None or abs(A[i] - prev) <= K:
            return max(dp(i + 1, prev), dp(i + 1, A[i]) + 1)
        else:
            return dp(i + 1, prev)

N, K = list(map(int, input().split()))
A = [int(eval(input())) for _ in range(N)]
print((dp(0, None)))


# Optimized solution
from collections import defaultdict


N, K = list(map(int, input().split()))
A = [int(eval(input())) for _ in range(N)]
dp = defaultdict(int)
for a in A:
    for prev in list(dp.keys()):
        if abs(prev - a) <= K:
            dp[a] = max(dp[prev] + 1, dp[a])
    dp[a] = max(1, dp[a])
print((max(dp.values())))
# Original solution
class Segtree():  # Segtree

    ide_ele = 0  # 初期値(単位元)

    def segfunc(self, x, y):  # 区間にしたい操作
        return max(x, y)  # ex) max,min,gcd,lcm,sum,product

    def __init__(self, n):  # LIST: 配列の初期値
        self.num = 1 << (n - 1).bit_length()
        self.tree = [Segtree.ide_ele] * 2 * self.num
        for i in range(self.num - 1, 0, -1):  # 構築していく
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):  # k番目の値をxに更新
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):  # [l, r)のsegfuncしたものを得る
        res = self.ide_ele
        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


n, k = list(map(int, input().split()))
a = [int(eval(input())) for _ in range(n)]

num = max(a) + k + 1
seg_dp = Segtree(num)
for ai in a:
    tmp = seg_dp.query(max(ai - k, 0), min(ai + k + 1, num))
    seg_dp.update(ai, tmp + 1)
print((max(seg_dp.tree)))


# Optimized solution
class Segtree():

    def __init__(self, n):
        self.num = 1 << (n - 1).bit_length()
        self.tree = [0] * 2 * self.num
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = max(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = max(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = 0
        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = max(res, self.tree[l])
                l += 1
            if r & 1:
                res = max(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res


n, k = list(map(int, input().split()))
a = [int(eval(input())) for _ in range(n)]

num = max(a) + k + 1
seg_dp = Segtree(num)
for ai in a:
    tmp = seg_dp.query(max(ai - k, 0), min(ai + k + 1, num))
    seg_dp.update(ai, tmp + 1)
print((max(seg_dp.tree)))
# Original solution
class Segtree():
    def __init__(self, n):
        self.num = 1 << (n - 1).bit_length()
        self.tree = [0] * 2 * self.num
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = max(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = max(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = 0
        l, r = l + self.num, r + self.num
        while l < r:
            if l & 1:
                res = max(res, self.tree[l])
                l += 1
            if r & 1:
                res = max(res, self.tree[r - 1])
            l, r = l >> 1, r >> 1
        return res


n, k = list(map(int, input().split()))
a = [int(eval(input())) for _ in range(n)]

# 解説AC
a_max = max(a) + 1
seg_dp = Segtree(a_max)
for ai in a:
    tmp = seg_dp.query(max(ai - k, 0), min(ai + k + 1, a_max))
    seg_dp.update(ai, tmp + 1)
print((max(seg_dp.tree)))


# Optimized solution
class Segtree():
    def __init__(self, n):
        self.num = 1 << (n - 1).bit_length()
        self.tree = [0] * 2 * self.num
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = max(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = max(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = 0
        l, r = l + self.num, r + self.num
        while l < r:
            if l & 1:
                res = max(res, self.tree[l])
                l += 1
            if r & 1:
                res = max(res, self.tree[r - 1])
            l, r = l >> 1, r >> 1
        return res


n, k = list(map(int, input().split()))
a = [int(eval(input())) for _ in range(n)]

a_max = max(a) + 1
seg_dp = Segtree(a_max)
for ai in a:
    tmp = seg_dp.query(max(ai - k, 0), min(ai + k + 1, a_max))
    seg_dp.update(ai, tmp + 1)
print((max(seg_dp.tree)))
# Original solution
def segfunc(x, y): return max(x, y)

class SegmentTree:
    def __init__(self, arr):
        size = len(arr)
        n = 2 ** (size - 1).bit_length()
        self.n = n
        self.node = [0] * (2*n)
        for i in range(size):
            self.node[i+n-1] = arr[i]
        for i in reversed(list(range(n-2))):
            self.node[i] = segfunc(self.node[2*i+1], self.node[2*i+2])

    def update(self, i, x):
        i += self.n - 1
        self.node[i] = x
        while i > 0:
            i = (i - 1) // 2
            self.node[i] = segfunc(self.node[i * 2 + 1], self.node[i * 2 + 2])

    def update(self, x, val):
        x += (self.n - 1)
        self.node[x] = val
        while x > 0:
            x = (x - 1) // 2
            self.node[x] = segfunc(self.node[2 * x + 1], self.node[2 * x + 2])

    def query(self, a, b):
        res = 0
        l = self.n - 1 + a
        r = self.n - 1 + (b - 1)

        while l <= r:
            if l == r:
                res = segfunc(res, self.node[l])
                break

            if l % 2 == 0:
                res = segfunc(res, self.node[l])
            if r % 2 == 1:
                res = segfunc(res, self.node[r])
            l = l // 2
            r = r // 2 - 1

        return res

N, K = list(map(int, input().split()))
INF = 0
seg = SegmentTree([0] * 300000)
for i in range(N):
    a = int(eval(input()))
    tmp = seg.query(max(a - K, 0), min(a + K, 300000) + 1) + 1
    seg.update(a, tmp)
print((seg.query(0, 300000)))


# Optimized solution
def segfunc(x, y): return max(x, y)
def update(i, x):
    i += MAX_N-1
    node[i] = x
    while i:
        i = (i-1)//2
        node[i] = segfunc(node[i*2+1], node[i*2+2])

def query(l, r):
    L = l + MAX_N
    R = r + MAX_N
    s = INF
    while L < R:
        if R & 1:
            R -= 1
            s = segfunc(s, node[R - 1])
        if L & 1:
            s = segfunc(s, node[L - 1])
            L += 1
        L >>= 1
        R >>= 1
    return s

N, K = list(map(int, input().split()))
MAX_N = 2**(300005).bit_length()
a = [int(eval(input())) for _ in range(N)]
node = [0] * (2 * MAX_N)
INF = 0
ans = 0

#for i in range(N):
#    update(i, a[i])

for i in a:
    tmp = query(max(i - K, 0), min(300005, i + K) + 1)
    update(i, tmp + 1)
    ans = max(ans, tmp + 1)
print(ans)
# Original solution
n,k=list(map(int,input().split()))
b=[int(eval(input())) for _ in range(n)]
dp=[[0]*(max(b)+1) for _ in range(n+1)]
a=b[0]
dp[1][a]=1
c=max(b)
for i in range(2,n+1):
    a=b[i-1]
    dp[i][a]=max(dp[i][a],1)
    for j in range(max(a-k,0),min(a+k,c+1)):
        if dp[i-1][j]!=0:
            dp[i][a-(a-j)]=max(dp[i-1][a-(a-j)],dp[i-1][j]+1)
    for j in range(c+1):
        dp[i][j]=max(dp[i][j],dp[i-1][j])
print((max(dp[-1])))


# Optimized solution
n,k=list(map(int,input().split()))
b=[int(eval(input())) for _ in range(n)]
dp=[0]*(max(b)+1)
c=max(b)
for i in range(n):
    dp[b[i]]=max(dp[b[i]],max(dp[max(0,b[i]-k):min(c+1,b[i]+k+1)])+1)
print((max(dp)))
# Original solution
N, K = list(map(int, input().split()))
l = []
for i in range(N):
  l.append(int(eval(input())))
  
cnts = [0] * 300001
for i in range(N):
  tmp = 0
  for j in range(max(l[i]-K, 0), min(l[i]+K+1, 300000)):
    tmp = max(tmp, cnts[j])
  cnts[l[i]] = tmp+1
print((max(cnts)))


# Optimized solution
N, K = list(map(int, input().split()))
l = []
for i in range(N):
  l.append(int(eval(input())))
  
cnts = [1] * N
for i in range(N):
  for j in range(max(0, i-200), i):
    if abs(l[i]-l[j]) <= K:
      cnts[i] = max(cnts[i], cnts[j]+1)
print((max(cnts)))
# Original solution
import sys
input = sys.stdin.buffer.readline
INF = 0

class MaxSegTree:
    """
    0-indexed
    query : [L, R)
    """
    def __init__(self, size):
        self.size = 1 << (size.bit_length())  # 完全二分木にする
        self.data = [-INF] * (2 * self.size - 1)

    def build(self, rawData):
        self.data[self.size - 1: self.size - 1 + len(rawData)] = rawData
        for i in range(self.size - 1)[:: -1]:
            self.data[i] = max(self.data[2 * i + 1], self.data[2 * i + 2])

    def update(self, index, value):
        index += self.size - 1
        if self.data[index] >= value:
            return
        self.data[index] = value
        while index >= 0:
            index = (index - 1) // 2
            self.data[index] = max(self.data[2 * index + 1], self.data[2 * index + 2])

    def query(self, left, right):
        L = left + self.size
        R = right + self.size
        ret = -INF
        while L < R:
            if R & 1:
                R -= 1
                ret = max(ret, self.data[R - 1])
            if L & 1:
                ret = max(ret, self.data[L - 1])
                L += 1
            L >>= 1
            R >>= 1
        return ret

N, K = list(map(int, input().split()))
A = [int(eval(input())) for _ in range(N)]
mxA = max(A)
tree = MaxSegTree(mxA + 10)

for a in A:
    nx = tree.query(max(0, a - K), min(mxA + 1, a + K + 1))
    tree.update(a, nx + 1)

print((tree.query(0, mxA + 1)))


# Optimized solution
import sys
input = sys.stdin.buffer.readline
INF = 0

class MaxSegTree:
    """
    0-indexed
    query : [L, R)
    """
    def __init__(self, size):
        self.size = 1 << (size.bit_length())  # 完全二分木にする
        self.data = [-INF] * (2 * self.size - 1)

    def build(self, rawData):
        self.data[self.size - 1: self.size - 1 + len(rawData)] = rawData
        for i in range(self.size - 1)[:: -1]:
            self.data[i] = max(self.data[2 * i + 1], self.data[2 * i + 2])

    def update(self, index, value):
        index += self.size - 1
        if self.data[index] >= value:
            return
        self.data[index] = value
        while index >= 0:
            index = (index - 1) // 2
            self.data[index] = max(self.data[2 * index + 1], self.data[2 * index + 2])

    def query(self, left, right):
        L = left + self.size
        R = right + self.size
        ret = -INF
        while L < R:
            if R & 1:
                R -= 1
                ret = max(ret, self.data[R - 1])
            if L & 1:
                ret = max(ret, self.data[L - 1])
                L += 1
            L >>= 1
            R >>= 1
        return ret

N, K = list(map(int, input().split()))
A = [int(eval(input())) for _ in range(N)]
mxA = max(A)
tree = MaxSegTree(mxA + 10)

for a in A:
    nx = tree.query(max(0, a - K), min(mxA, a + K) + 1)
    tree.update(a, nx + 1)

print((tree.query(0, mxA + 1)))