CodeEff/ECCO huggingface dataset:
# Original solution

import sys
# sys.setrecursionlimit(100000)


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


def input_int():
    return int(eval(input()))


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


class SegTree:
    X_unit = 0
    X_f = max

    def __init__(self, N):
        self.N = N
        self.X = [self.X_unit] * (N + 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])

    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:
            if L & 1:
                vL = self.X_f(vL, self.X[L])
                L += 1
            if R & 1:
                R -= 1
                vR = self.X_f(self.X[R], vR)
            L >>= 1
            R >>= 1
        return self.X_f(vL, vR)


def main():
    n, k = input_int_list()
    segtree = SegTree(500000)
    for _ in range(n):
        a = input_int()

        val = segtree.fold(max(0, a - k), min(500000, a + k + 1))
        segtree.set_val(a, val + 1)

    print((segtree.X[1]))

    return


if __name__ == "__main__":
    main()


# Optimized solution

import sys
# sys.setrecursionlimit(100000)


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


def input_int():
    return int(eval(input()))


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


class SegTree:
    X_unit = 0
    X_f = max

    def __init__(self, N):
        self.N = N
        self.X = [self.X_unit] * (N + 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])

    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:
            if L & 1:
                vL = self.X_f(vL, self.X[L])
                L += 1
            if R & 1:
                R -= 1
                vR = self.X_f(self.X[R], vR)
            L >>= 1
            R >>= 1
        return self.X_f(vL, vR)


def main():
    n, k = input_int_list()
    segtree = SegTree(300001)
    for _ in range(n):
        a = input_int()

        val = segtree.fold(max(0, a - k), min(300001, a + k + 1))
        segtree.set_val(a, val + 1)

    print((segtree.X[1]))

    return


if __name__ == "__main__":
    main()
# Original solution
# 1-index
def segfunc(x, y):
    return max(x, y)

ide_ele = 0

class segtree:

    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num

        for i in range(n):
            self.tree[self.num + i] = init_val[i]

        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 += 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()))
T = []
for i in range(N):
    a = int(eval(input()))
    T.append(a)

A = [0]*(max(T)+1)
s_tree = segtree(A, segfunc, ide_ele)
for i in range(N):
    a = T[i]
    p = s_tree.query(max(a - K, 0), min(a + K + 1, max(T)+1))
    s_tree.update(a, p + 1)

print((s_tree.query(0, max(T)+1)))

# Optimized solution
# 1-index
def segfunc(x, y):
    return max(x, y)

ide_ele = 0

class segtree:

    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num

        for i in range(n):
            self.tree[self.num + i] = init_val[i]

        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 += 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()))
T = []
for i in range(N):
    a = int(eval(input()))
    T.append(a)

M = max(T)+1
A = [0]*M
s_tree = segtree(A, segfunc, ide_ele)
for i in range(N):
    a = T[i]
    p = s_tree.query(max(a - K, 0), min(a + K + 1, M))
    s_tree.update(a, p + 1)

print((s_tree.query(0, M)))
# Original solution
# coding: utf-8
# Your code here!
N,K = list(map(int,input().split()))
A = [int(eval(input())) for _ in range(N)]
dp = [[0] * N for _ in range(N)]
dp2 = [0] * N
for i in range(N):
    for j in range(i,N):
        if abs(A[i]-A[j]) <= K:
            dp[i][j] = 1
for i in range(N):
    tmax = 1
    for j in range(i+1):
        if dp[j][i]==1:
            tmax = max(tmax,dp2[j]+1)
    dp2[i] = tmax  

print((max(dp2)))



# Optimized solution
N,K = list(map(int,input().split()))
A = [int(eval(input())) for _ in range(N)]
dp2 = [0] * N
for i in range(N):
    tmax = 0
    for j in range(i+1):
        if abs(A[i]-A[j]) <= K:
            tmax = max(tmax,dp2[j]+1)
    dp2[i] = tmax  

print((max(dp2)))
# Original solution
from math import ceil, log2
class SegTree:
    ide_ele = 0
    def __init__(self, init_val):
        n = len(init_val)
        self.num = 2**ceil(log2(n))
        self.seg = [self.ide_ele] * (2 * self.num - 1)

    def segfunc(self, x, y):
        return max(x, y)

    def update(self, k, x):
        k += self.num - 1
        self.seg[k] = x
        while k:
            k = (k - 1) // 2
            self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return self.ide_ele
        if a <= l and r <= b:
            return self.seg[k]
        else:
            vl = self.query(a, b, k*2+1, l, (l+r)//2)
            vr = self.query(a, b, k*2+2, (l+r)//2, r)
            return self.segfunc(vl, vr)


n, k = list(map(int, input().split()))
a = [int(eval(input())) for _ in range(n)]
M=300001
st = SegTree([0]*M)
res = 0
for i in a:
    min_a = max(i-k, 0)
    max_a = min(i+k, M)
    s = st.query(min_a, max_a+1, 0, 0, st.num)
    st.update(i, max(s, 0)+1)
    res = max(res, max(s, 0) + 1)

print(res)


# Optimized solution
from math import ceil, log2
import sys
z=sys.stdin.readline
class SegTree:
    ide_ele = 0
    def __init__(self, init_val):
        n = len(init_val)
        self.num = 2**ceil(log2(n))
        self.seg = [self.ide_ele] * (2 * self.num - 1)

    def segfunc(self, x, y):
        return max(x, y)

    def update(self, k, x):
        k += self.num - 1
        self.seg[k] = x
        while k:
            k = (k - 1) // 2
            self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

    def query(self, a, b, k, l, r):
        if r <= a or b <= l:
            return self.ide_ele
        if a <= l and r <= b:
            return self.seg[k]
        else:
            vl = self.query(a, b, k*2+1, l, (l+r)//2)
            vr = self.query(a, b, k*2+2, (l+r)//2, r)
            return self.segfunc(vl, vr)


n, k = list(map(int, z().split()))
a = [int(z()) for _ in range(n)]
M=300001
st = SegTree([0]*M)
res = 0
for i in a:
    min_a = max(i-k, 0)
    max_a = min(i+k, M)
    s = st.query(min_a, max_a+1, 0, 0, st.num)
    st.update(i, max(s, 0)+1)
    res = max(res, max(s, 0) + 1)

print(res)
# Original solution
n,k=list(map(int,input().split()))
a=[int(eval(input())) for i in range(n)]
subs=[[] for i in range(n)]

idx=0
for ai in a:
  for i in range(idx+1):
    if len(subs[i])==0:
      subs[i].append(ai)
      idx+=1
      break
    else:
      if abs(subs[i][-1]-ai)<=k:
        subs[i].append(ai)

ans=0
for i in range(idx):
  #print(subs[i])
  ans=max(ans,len(subs[i]))
print(ans)

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

l[0].append(a[0])
ans=0
for ai in a[1:]:
  for i in reversed(list(range(ans+1))): # if can a_i put backword, add l[i+1]. because of maximum length answer 
    for li in l[i]:
      if -k<=(li-ai)<=k:
        ans=max(ans,i+1)
        l[i+1].append(ai)
        break
    else:
      continue
    break
  else:
    l[0].append(ai)

print((ans+1))
# Original solution
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)



# Optimized solution
# セグメント木
# 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)
# Original solution
n, k = list(map(int, input().split()))
l = []
for i in range(n):
    l.append(int(eval(input())))

root = [1]*n

for i in range(n)[-2::-1]:
    num = 0
    for j in range(i + 1, i + 500):
        if j >= n:
            break
        if abs(l[i] - l[j]) <= k:
            num = max(num, root[j])
    root[i] += num

print((max(root)))

# Optimized solution
n, k = list(map(int, input().split()))
l = []
for i in range(n):
    l.append(int(eval(input())))

root = [1]*n

for i in range(n)[-2::-1]:
    num = 0
    for j in range(i + 1, i + 200):
        if j >= n:
            break
        if abs(l[i] - l[j]) <= k:
            num = max(num, root[j])
    root[i] += num

print((max(root)))
# Original solution
from bisect import bisect_left

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

t = [[] for _ in range(N)]

ans = 0
for i in range(N):
    for j in range(len(t)-1, -1, -1):
        idx = bisect_left(t[j], A[i])
        if idx != len(t[j]):
            if abs(t[j][idx] - A[i]) <= K:
                t[j+1].append(A[i])
                ans = max(ans, j+2)
                break
        elif idx > 0:
            if abs(t[j][idx-1] -A[i]) <= K:
                t[j+1].append(A[i])
                ans = max(ans, j+2)
                break
    else:
        t[0].append(A[i])
        ans = max(ans, 1)

print(ans)

# Optimized solution
from bisect import bisect_left

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

t = [[] for _ in range(N)]

ans = 0
for i in range(N):
    for j in range(ans-1, -1, -1):
        idx = bisect_left(t[j], A[i])
        if idx != len(t[j]):
            if abs(t[j][idx] - A[i]) <= K:
                t[j + 1].insert(bisect_left(t[j + 1], A[i]), A[i])
                ans = max(ans, j+2)
                break
        if idx > 0:
            if abs(t[j][idx-1] - A[i]) <= K:
                t[j + 1].insert(bisect_left(t[j + 1], A[i]), A[i])
                ans = max(ans, j+2)
                break
    else:
        t[0].insert(bisect_left(t[0], A[i]), A[i])
        ans = max(ans, 1)

print(ans)
# Original solution
d=[0]*6**8
n,k,*a=list(map(int,open(0).read().split()+d))
for i in range(n):d[i]=max(d[j]for j in range(i-99,i+1)if abs(a[i]-a[j])<=k)+1
print((max(d)))

# Optimized solution
d=[0]*6**8
n,k,*a=list(map(int,open(0).read().split()))
a=d+a
while n:d[n]=max(d[j]for j in range(n,n+99)if abs(a[-n]-a[-j])<=k)+1;n-=1
print((max(d)))
# Original solution
d=[0]*6**8
n,k,*a=list(map(int,open(0).read().split()+d))
while n:n-=1;d[n]=max(d[j]for j in range(n,n+99)if abs(a[n]-a[j])<=k)+1
print((max(d)))

# Optimized solution
d=[0]*6**8
n,k,*a=list(map(int,open(0).read().split()+d))
while n:n-=1;d[n]=max(d[j]for j in range(n,n+99)if-k<=a[n]-a[j]<=k)+1
print((max(d)))
# Original solution
d=[0]*6**8
n,k,*a=list(map(int,open(0).read().split()+d))
while n:n-=1;d[n]=max(d[j]for j in range(n,n+99)if-k<=a[n]-a[j]<=k)+1
print((max(d)))

# Optimized solution
d=[0]*6**8
n,k,*a=list(map(int,open(0).read().split()+d))
while n:n-=1;d[n]=max(d[j]for j in range(n,n+99)if~k<a[n]-a[j]<=k)+1
print((max(d)))
# Original solution
N, K = list(map(int, input().split()))

BL = (300000).bit_length()
WIDTH = pow(2, BL)
BUFSIZE = pow(2, BL+1) - 1
BASE = BUFSIZE - WIDTH

# TODO: default value
buf = [0] * BUFSIZE

def update(i, x):
    i += BASE
    buf[i] = x
    i = (i-1) // 2
    while i >= 0:
        buf[i] = compare(buf[2*i+1], buf[2*i+2])
        i = (i-1) // 2

# [q_left, q_right]
def search(q_left, q_right):
    return _search(0, WIDTH, 0, q_left, q_right)

def _search(l, width, i, q_left, q_right):
    if q_right < l or l + width - 1 < q_left:
        return 0
    if q_left <= l and l + width - 1 <= q_right:
        return buf[i]
    nwidth = width // 2
    c1 = _search(l, nwidth, 2*i+1, q_left, q_right)
    c2 = _search(l+nwidth, nwidth, 2*i+2, q_left, q_right)
    return compare(c1, c2)

def compare(i1, i2):
    if i1 > i2:
        return i1
    else:
        return i2

for _ in range(N):
    a = int(eval(input()))
    maxlen = search(a-K, a+K)
    update(a, maxlen+1)
print((search(0, 300000)))


# Optimized solution
import sys
input = sys.stdin.readline
N, K = list(map(int, input().rstrip().split()))

BL = (300001-1).bit_length()
WIDTH = pow(2, BL)
BUFSIZE = pow(2, BL+1) - 1
BASE = BUFSIZE - WIDTH
DEFAULT = 0

buf = [DEFAULT] * BUFSIZE

def update(i, x):
    i += BASE
    buf[i] = x
    i = (i-1) // 2
    while i >= 0:
        buf[i] = compare(buf[2*i+1], buf[2*i+2])
        i = (i-1) // 2

# [q_left, q_right]
def search(left, right):
    ansl = ansr = DEFAULT
    left += BASE
    right += BASE
    while left < right:
        if not (left & 1):
            ansl = compare(ansl, buf[left])
            left += 1
        if right & 1:
            ansr = compare(ansr, buf[right])
            right -= 1
        left = (left-1) // 2
        right = (right-1) // 2
    if left == right:
        ansl = compare(ansl, buf[left])
    return compare(ansl, ansr)

def compare(v1, v2):
    return v1 if v1 > v2 else v2

for _ in range(N):
    a = int(input().rstrip())
    maxlen = search(max(0, a-K), min(a+K, 300000))
    update(a, maxlen+1)
print((search(0, 300000)))
# Original solution


n,k = list(map(int,input().split()))
a=[0 for i in range(n)]
for i in range(n):
    a[i] = int(eval(input()))
rank=[0 for i in range(n)]

rank[0]=1
for i in range(1,n):
    ap = a[i]
    r=0
    for j in range(i):
        if abs(a[j]-ap)<=k:
            r=max(r,rank[j])
    rank[i]=r+1
print((max(rank)))

# Optimized solution


n,k = list(map(int,input().split()))
a=[0 for i in range(n)]
for i in range(n):
    a[i] = int(eval(input()))
rank=[[] for i in range(n)]

ans = 1
for i in range(n):
    for r in range(ans,-1,-1):
        frag = 0
        for j in rank[r]:
            if abs(j-a[i])<=k:
                rank[r+1].append(a[i])
                ans = max(ans,r+2)
                frag =1
                break
        rank[0].append(a[i])
        if frag ==1:
            break


print((ans-1))
# Original solution
class SEGTree:
    def __init__(self,n,op,e):
        self.Unit=e
        self.Op=op
        i=1<<(n.bit_length()-1)
        if i!=n:
            i*=2
        self.SEG=[self.Unit]*(2*i-1)
        self.d=i
    def update(self,i,x):
        i+=self.d-1
        self.SEG[i]=x
        while i>0:
            i=(i-1)//2
            self.SEG[i]=self.Op(self.SEG[i*2+1],self.SEG[i*2+2])
    def find(self,a,b,k,l,r):
        if r<=a or b<=l:
            return self.Unit
        if a<=l and r<=b:
            return self.SEG[k]
        else:
            c1=self.find(a,b,2*k+1,l,(l+r)//2)
            c2=self.find(a,b,2*k+2,(l+r)//2,r)
            return self.Op(c1,c2)
    def get(self,a,b):
        return self.find(a,b,0,0,self.d)

INF=10**30
N,K=list(map(int,input().split()))
A=[int(eval(input())) for i in range(N)]
M=max(A)
SEG=SEGTree(M+1,max,0)

ans=0
for i in range(N):
    l=max(0,A[i]-K)
    r=min(M,A[i]+K)
    res=SEG.get(l,r+1)
    ans=max(ans,res+1)
    if SEG.get(A[i],A[i]+1)<res+1:
        SEG.update(A[i],res+1)
print(ans)

# Optimized solution
import sys
input=sys.stdin.readline

class SEGTree:
    def __init__(self,N,op,e):
        self.size=2**(N-1).bit_length()
        self.e=e
        self.op=op
        self.SEG=[self.e]*(self.size*2)
    
    def update(self,i,x):
        i+=self.size
        self.SEG[i]=x
        while i>0:
            i>>=1
            self.SEG[i]=self.op(self.SEG[i*2],self.SEG[i*2+1])
            
    def query(self,l,r):
        l+=self.size
        r+=self.size
        lres,rres=self.e,self.e
        
        while l<r:
            if l&1:
                lres=self.op(lres,self.SEG[l])
                l+=1
            if r&1:
                r-=1
                rres=self.op(self.SEG[r],rres)
            l>>=1
            r>>=1
        res=self.op(lres,rres)
        return res
    
    def get(self,i):
        return self.SEG[i+self.size]

N,K=list(map(int,input().split()))
A=[int(eval(input())) for i in range(N)]
M=max(A)
seg=SEGTree(M+1,max,0)
 
ans=0
for i in range(N):
    l=max(0,A[i]-K)
    r=min(M,A[i]+K)
    res=seg.query(l,r+1)+1
    ans=max(ans,res)
    if seg.get(A[i])<res:
        seg.update(A[i],res)
print(ans)
# Original solution
n, k = list(map(int, input().split()))
a_list = [int(eval(input())) for _ in range(n)]

dp = [1] * n

for i in range(n):
    for j in range(max(0, i-n), i):
        if abs(a_list[i] - a_list[j]) <= k:
            dp[i] = max(dp[i], dp[j] + 1)

ans = max(dp)
print(ans)

# Optimized solution
n, k = list(map(int, input().split()))
a_list = [int(eval(input())) for _ in range(n)]

dp = [1] * n

for i in range(n):
    for j in range(max(0, i - 100), i):
        if abs(a_list[i] - a_list[j]) <= k:
            dp[i] = max(dp[i], dp[j] + 1)

ans = max(dp)
print(ans)
# Original solution
import sys

input = sys.stdin.buffer.readline

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

max_n = 300000
num = 1 << ((max_n - 1).bit_length())
SEG = [0] * (2 * num)

func = max
ele = 0


def update(idx, val):
    idx += num
    SEG[idx] = val
    for i in reversed(list(range(1, num))):
        SEG[i] = func(SEG[2 * i], SEG[2 * i + 1])


def query(left, right):
    res_left = ele
    res_right = ele
    left += num
    right += num
    while left < right:
        if left & 1:
            res_left = func(res_left, SEG[left])
            left += 1
        if right & 1:
            right -= 1
            res_right = func(SEG[right], res_right)
        left //= 2
        right //= 2
    return func(res_left, res_right)


for _ in range(n):
    val = int(eval(input()))
    temp = query(max(0, val - k), min(max_n + 1, val + k + 1))
    temp += 1
    update(val, temp)


print((SEG[1]))



# Optimized solution
import sys

input = sys.stdin.buffer.readline


class SegmentTree:
    ele = 0
    func = max
    # SEG木は1-index
    # Aに関しては0-index

    def __init__(self, n):  # Aは0-idx
        self.n = n
        self.num = 2 ** ((self.n - 1).bit_length())
        self.SEG = [self.ele] * (2 * self.num)

    def search(self, idx):
        return self.SEG[idx + self.num]

    def initialize(self, A):
        for i in range(self.n):
            self.SEG[i + self.num] = A[i]
        for i in range(self.num - 1, 0, -1):
            self.SEG[i] = self.func(self.SEG[2 * i], self.SEG[2 * i + 1])

    # 1点更新
    def set(self, idx, val):
        idx += self.num
        self.SEG[idx] = val
        idx //= 2
        while idx:
            self.SEG[idx] = self.func(self.SEG[2 * idx], self.SEG[2 * idx + 1])
            idx //= 2

    # 区間取得
    def query(self, left, right):
        # 開区間
        resleft = self.ele
        resright = self.ele
        left += self.num
        right += self.num
        while right - left > 0:
            if left % 2 == 1:
                resleft = self.func(resleft, self.SEG[left])
                left += 1
            if right % 2 == 1:
                right -= 1
                resright = self.func(resright, self.SEG[right])
            left //= 2
            right //= 2
        return self.func(resleft, resright)


n, k = list(map(int, input().split()))
ans = 0
ST = SegmentTree(3000001)
for _ in range(n):
    val = int(eval(input()))
    lower = val - k
    lower = max(lower, 0)
    upper = val + k
    upper = min(upper, 3000000)
    temp = ST.query(lower, upper + 1) + 1
    ST.set(val, temp)
    ans = max(ans, temp)
print(ans)