import sys

input = sys.stdin.readline



n,k = list(map(int, input().split()))

As = [int(eval(input())) for i in range(n)]



# N: 処理する区間の長さ



INF = 0



mx = 300001

LV = (mx-1).bit_length()

N0 = 2**LV

data = [INF]*(2*N0)

lazy = [None]*(2*N0)



# 伝搬対象の区間を求める

def gindex(l, r):

    L = (l + N0) >> 1; R = (r + N0) >> 1

    lc = 0 if l & 1 else (L & -L).bit_length()

    rc = 0 if r & 1 else (R & -R).bit_length()

    for i in range(LV):

        if rc <= i:

            yield R

        if L < R and lc <= i:

            yield L

        L >>= 1; R >>= 1



# 遅延伝搬処理

def propagates(*ids):

    for i in reversed(ids):

        v = lazy[i-1]

        if v is None:

            continue

        lazy[2*i-1] = data[2*i-1] = lazy[2*i] = data[2*i] = v

        lazy[i-1] = None



# 区間[l, r)をxで更新

def update(l, r, x):

    *ids, = gindex(l, r)

    propagates(*ids)



    L = N0 + l; R = N0 + r

    while L < R:

        if R & 1:

            R -= 1

            lazy[R-1] = data[R-1] = x

        if L & 1:

            lazy[L-1] = data[L-1] = x

            L += 1

        L >>= 1; R >>= 1

    for i in ids:

        data[i-1] = max(data[2*i-1], data[2*i])



# 区間[l, r)内の最小値を求める

def query(l, r):

    propagates(*gindex(l, r))

    L = N0 + l; R = N0 + r



    s = INF

    while L < R:

        if R & 1:

            R -= 1

            s = max(s, data[R-1])

        if L & 1:

            s = max(s, data[L-1])

            L += 1

        L >>= 1; R >>= 1

    return s



ans = 0

update(As[0],As[0]+1,1)

for i, a in enumerate(As[1:]):

    l = max(0,a-k)

    r = min(mx,a+k)

    upd = query(l,r+1)

    if upd == -1:continue

    # print("i",i,"a",a,"upd",upd,"l",l,"r",r)

    update(a, a+1, upd+1)

    ans = max(ans, upd+1)

print(ans)



# セグメント木

# segment tree

import sys

input = sys.stdin.readline



class segmented_tree:

    X_unit = 0

    X_f = lambda self, a, b: max(a,b)

    def __init__(self, N):

        self.N = N

        self.X = [self.X_unit] * (2*N)

        

    def build(self, seq):

        for i, x in enumerate(seq, self.N):

            self.X[i] = x 

        # 後ろから入れていく

        for i in range(self.N-1, 0, -1):

            self.X[i] = self.X_f(self.X[i<<1], self.X[i<<1|1])



    # 1点更新

    def set_val(self, i, x):

        i += self.N

        self.X[i] = x

        while i > 1:

            i >>= 1

            self.X[i] = self.X_f(self.X[i<<1],self.X[i<<1|1])

    

    # 区間取得

    def fold(self, l, r):

        l += self.N

        r += self.N

        vl = self.X_unit

        vr = self.X_unit

        # 外から決めていく

        while l < r:

            # print(l,r)

            if l & 1:

                vl = self.X_f(vl, self.X[l])

                l += 1

            if r & 1:

                r -= 1

                vr = self.X_f(vr, self.X[r])

            l >>= 1

            r >>= 1

        return self.X_f(vl,vr)



n,k = list(map(int, input().split()))

As = [int(eval(input())) for i in range(n)]

mx = 300001

ans = 0

sg = segmented_tree(330000)



for a in As:

    l = max(0,a-k)

    r = min(mx,a+k)



    upd = sg.fold(l,r+1)

    ans = max(ans, upd+1)



    sg.set_val(a, upd+1)

print(ans)



import sys

input = sys.stdin.readline
n, k = list(map(int, input().split()))
As = [int(eval(input())) for i in range(n)]
# N: 処理する区間の長さ
INF = 0
mx = 300001
LV = (mx - 1).bit_length()
N0 = 2**LV
data = [INF] * (2 * N0)
lazy = [None] * (2 * N0)
# 伝搬対象の区間を求める
def gindex(l, r):
    L = (l + N0) >> 1
    R = (r + N0) >> 1
    lc = 0 if l & 1 else (L & -L).bit_length()
    rc = 0 if r & 1 else (R & -R).bit_length()
    for i in range(LV):
        if rc <= i:
            yield R
        if L < R and lc <= i:
            yield L
        L >>= 1
        R >>= 1


# 遅延伝搬処理
def propagates(*ids):
    for i in reversed(ids):
        v = lazy[i - 1]
        if v is None:
            continue
        lazy[2 * i - 1] = data[2 * i - 1] = lazy[2 * i] = data[2 * i] = v
        lazy[i - 1] = None


# 区間[l, r)をxで更新
def update(l, r, x):
    (*ids,) = gindex(l, r)
    propagates(*ids)
    L = N0 + l
    R = N0 + r
    while L < R:
        if R & 1:
            R -= 1
            lazy[R - 1] = data[R - 1] = x
        if L & 1:
            lazy[L - 1] = data[L - 1] = x
            L += 1
        L >>= 1
        R >>= 1
    for i in ids:
        data[i - 1] = max(data[2 * i - 1], data[2 * i])


# 区間[l, r)内の最小値を求める
def query(l, r):
    propagates(*gindex(l, r))
    L = N0 + l
    R = N0 + r
    s = INF
    while L < R:
        if R & 1:
            R -= 1
            s = max(s, data[R - 1])
        if L & 1:
            s = max(s, data[L - 1])
            L += 1
        L >>= 1
        R >>= 1
    return s


ans = 0
update(As[0], As[0] + 1, 1)
for i, a in enumerate(As[1:]):
    l = max(0, a - k)
    r = min(mx, a + k)
    upd = query(l, r + 1)
    if upd == -1:
        continue
    # print("i",i,"a",a,"upd",upd,"l",l,"r",r)
    update(a, a + 1, upd + 1)
    ans = max(ans, upd + 1)
print(ans)

# セグメント木
# segment tree
import sys

input = sys.stdin.readline


class segmented_tree:
    X_unit = 0
    X_f = lambda self, a, b: max(a, b)

    def __init__(self, N):
        self.N = N
        self.X = [self.X_unit] * (2 * N)

    def build(self, seq):
        for i, x in enumerate(seq, self.N):
            self.X[i] = x
        # 後ろから入れていく
        for i in range(self.N - 1, 0, -1):
            self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1])

    # 1点更新
    def set_val(self, i, x):
        i += self.N
        self.X[i] = x
        while i > 1:
            i >>= 1
            self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1])

    # 区間取得
    def fold(self, l, r):
        l += self.N
        r += self.N
        vl = self.X_unit
        vr = self.X_unit
        # 外から決めていく
        while l < r:
            # print(l,r)
            if l & 1:
                vl = self.X_f(vl, self.X[l])
                l += 1
            if r & 1:
                r -= 1
                vr = self.X_f(vr, self.X[r])
            l >>= 1
            r >>= 1
        return self.X_f(vl, vr)


n, k = list(map(int, input().split()))
As = [int(eval(input())) for i in range(n)]
mx = 300001
ans = 0
sg = segmented_tree(330000)
for a in As:
    l = max(0, a - k)
    r = min(mx, a + k)
    upd = sg.fold(l, r + 1)
    ans = max(ans, upd + 1)
    sg.set_val(a, upd + 1)
print(ans)

+# セグメント木 +# segment tree + + +class segmented_tree: +    X_unit = 0 +    X_f = lambda self, a, b: max(a, b) + +    def __init__(self, N): +        self.N = N +        self.X = [self.X_unit] * (2 * N) + +    def build(self, seq): +        for i, x in enumerate(seq, self.N): +            self.X[i] = x +        # 後ろから入れていく +        for i in range(self.N - 1, 0, -1): +            self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1]) + +    # 1点更新 +    def set_val(self, i, x): +        i += self.N +        self.X[i] = x +        while i > 1: +            i >>= 1 +            self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1]) + +    # 区間取得 +    def fold(self, l, r): +        l += self.N +        r += self.N +        vl = self.X_unit +        vr = self.X_unit +        # 外から決めていく +        while l < r: +            # print(l,r) +            if l & 1: +                vl = self.X_f(vl, self.X[l]) +                l += 1 +            if r & 1: +                r -= 1 +                vr = self.X_f(vr, self.X[r]) +            l >>= 1 +            r >>= 1 +        return self.X_f(vl, vr) + + -# N: 処理する区間の長さ -INF = 0 -LV = (mx - 1).bit_length() -N0 = 2**LV -data = [INF] * (2 * N0) -lazy = [None] * (2 * N0) -# 伝搬対象の区間を求める -def gindex(l, r): -    L = (l + N0) >> 1 -    R = (r + N0) >> 1 -    lc = 0 if l & 1 else (L & -L).bit_length() -    rc = 0 if r & 1 else (R & -R).bit_length() -    for i in range(LV): -        if rc <= i: -            yield R -        if L < R and lc <= i: -            yield L -        L >>= 1 -        R >>= 1 - - -# 遅延伝搬処理 -def propagates(*ids): -    for i in reversed(ids): -        v = lazy[i - 1] -        if v is None: -            continue -        lazy[2 * i - 1] = data[2 * i - 1] = lazy[2 * i] = data[2 * i] = v -        lazy[i - 1] = None - - -# 区間[l, r)をxで更新 -def update(l, r, x): -    (*ids,) = gindex(l, r) -    propagates(*ids) -    L = N0 + l -    R = N0 + r -    while L < R: -        if R & 1: -            R -= 1 -            lazy[R - 1] = data[R - 1] = x -        if L & 1: -            lazy[L - 1] = data[L - 1] = x -            L += 1 -        L >>= 1 -        R >>= 1 -    for i in ids: -        data[i - 1] = max(data[2 * i - 1], data[2 * i]) - - -# 区間[l, r)内の最小値を求める -def query(l, r): -    propagates(*gindex(l, r)) -    L = N0 + l -    R = N0 + r -    s = INF -    while L < R: -        if R & 1: -            R -= 1 -            s = max(s, data[R - 1]) -        if L & 1: -            s = max(s, data[L - 1]) -            L += 1 -        L >>= 1 -        R >>= 1 -    return s - - -update(As[0], As[0] + 1, 1) -for i, a in enumerate(As[1:]): +sg = segmented_tree(330000) +for a in As: -    upd = query(l, r + 1) -    if upd == -1: -        continue -    # print("i",i,"a",a,"upd",upd,"l",l,"r",r) -    update(a, a + 1, upd + 1) +    upd = sg.fold(l, r + 1) +    sg.set_val(a, upd + 1)