class LazySegmentTree:

    def __init__(self, data, default=0, func=max):

        """initialize the lazy segment tree with data"""

        self._default = default

        self._func = func



        self._len = len(data)

        self._size = _size = 1 << (self._len - 1).bit_length()

        self._lazy = [0] * (2 * _size)



        self.data = [default] * (2 * _size)

        self.data[_size:_size + self._len] = data

        for i in reversed(list(range(_size))):

            self.data[i] = func(self.data[i + i], self.data[i + i + 1])



    def __len__(self):

        return self._len



    def _push(self, idx):

        """push query on idx to its children"""

        # Let the children know of the queries

        q, self._lazy[idx] = self._lazy[idx], 0



        if q:

            self._lazy[2 * idx] = max(self._lazy[2 * idx],q)

            self._lazy[2 * idx + 1] = max(self._lazy[2 * idx + 1],q)

            self.data[2 * idx] = max(self.data[2 * idx], q)

            self.data[2 * idx + 1] = max(self.data[2 * idx + 1], q)



    def _update(self, idx):

        """updates the node idx to know of all queries applied to it via its ancestors"""

        for i in reversed(list(range(1, idx.bit_length()))):

            self._push(idx >> i)



    def _build(self, idx):

        """make the changes to idx be known to its ancestors"""

        idx >>= 1

        while idx:

            self.data[idx] = max(self.data[idx], self._func(self.data[2 * idx], self.data[2 * idx + 1]))

            self._push(idx)

            idx >>= 1



    def add(self, start, stop, value):

        """lazily add value to [start, stop)"""

        start = start_copy = start + self._size

        stop = stop_copy = stop + self._size

        while start < stop:

            #print('a', start, stop)

            if start & 1:

                self._lazy[start] = max(self._lazy[start], value)

                self.data[start] = max(self.data[start],value)

                start += 1

            if stop & 1:

                stop -= 1

                self._lazy[stop] = max(self._lazy[stop], value)

                self.data[stop] = max(self.data[stop],value)

            start >>= 1

            stop >>= 1



        # Tell all nodes above of the updated area of the updates

        self._build(start_copy)

        self._build(stop_copy - 1)



    def query(self, start, stop, default=0):

        """func of data[start, stop)"""

        start += self._size

        stop += self._size



        # Apply all the lazily stored queries

        self._update(start)

        self._update(stop - 1)



        res = default

        while start < stop:

            if start & 1:

                res = self._func(res, self.data[start])

                start += 1

            if stop & 1:

                stop -= 1

                res = self._func(res, self.data[stop])

            start >>= 1

            stop >>= 1

        return res



    def __repr__(self):

        return "LazySegmentTree({0})".format(self.data)



import sys

input = sys.stdin.readline



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

seg = LazySegmentTree([0] * (1 << 20))

for _ in range(n):

    v = int(eval(input()))

    most = seg.query(v, v+1)

    #print(most)

    seg.add(max(0,v - k), v + k + 1, most + 1)

    #print(seg.data)

print((seg.query(0, 1 << 20)))

class SegmentTree:

    def __init__(self, data, default=0, func=max):

        """initialize the segment tree with data"""

        self._default = default

        self._func = func

        self._len = len(data)

        self._size = _size = 1 << (self._len - 1).bit_length()



        self.data = [default] * (2 * _size)

        self.data[_size:_size + self._len] = data

        for i in reversed(list(range(_size))):

            self.data[i] = func(self.data[i + i], self.data[i + i + 1])



    def __delitem__(self, idx):

        self[idx] = self._default



    def __getitem__(self, idx):

        return self.data[idx + self._size]



    def __setitem__(self, idx, value):

        idx += self._size

        self.data[idx] = value

        idx >>= 1

        while idx:

            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])

            idx >>= 1



    def __len__(self):

        return self._len



    def query(self, start, stop):

        """func of data[start, stop)"""

        start += self._size

        stop += self._size



        res_left = res_right = self._default

        while start < stop:

            if start & 1:

                res_left = self._func(res_left, self.data[start])

                start += 1

            if stop & 1:

                stop -= 1

                res_right = self._func(self.data[stop], res_right)

            start >>= 1

            stop >>= 1



        return self._func(res_left, res_right)



    def __repr__(self):

        return "SegmentTree({0})".format(self.data)

    

import sys

input = sys.stdin.readline



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

seg = SegmentTree([0] * (1 << 20))

for _ in range(n):

    v = int(eval(input()))

    most = seg.query(max(0, v - k), v + k + 1)

    seg[v] = most + 1

print((seg.query(0, 1 << 20)))

class LazySegmentTree:
    def __init__(self, data, default=0, func=max):
        """initialize the lazy segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()
        self._lazy = [0] * (2 * _size)
        self.data = [default] * (2 * _size)
        self.data[_size : _size + self._len] = data
        for i in reversed(list(range(_size))):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __len__(self):
        return self._len

    def _push(self, idx):
        """push query on idx to its children"""
        # Let the children know of the queries
        q, self._lazy[idx] = self._lazy[idx], 0
        if q:
            self._lazy[2 * idx] = max(self._lazy[2 * idx], q)
            self._lazy[2 * idx + 1] = max(self._lazy[2 * idx + 1], q)
            self.data[2 * idx] = max(self.data[2 * idx], q)
            self.data[2 * idx + 1] = max(self.data[2 * idx + 1], q)

    def _update(self, idx):
        """updates the node idx to know of all queries applied to it via its ancestors"""
        for i in reversed(list(range(1, idx.bit_length()))):
            self._push(idx >> i)

    def _build(self, idx):
        """make the changes to idx be known to its ancestors"""
        idx >>= 1
        while idx:
            self.data[idx] = max(
                self.data[idx], self._func(self.data[2 * idx], self.data[2 * idx + 1])
            )
            self._push(idx)
            idx >>= 1

    def add(self, start, stop, value):
        """lazily add value to [start, stop)"""
        start = start_copy = start + self._size
        stop = stop_copy = stop + self._size
        while start < stop:
            # print('a', start, stop)
            if start & 1:
                self._lazy[start] = max(self._lazy[start], value)
                self.data[start] = max(self.data[start], value)
                start += 1
            if stop & 1:
                stop -= 1
                self._lazy[stop] = max(self._lazy[stop], value)
                self.data[stop] = max(self.data[stop], value)
            start >>= 1
            stop >>= 1
        # Tell all nodes above of the updated area of the updates
        self._build(start_copy)
        self._build(stop_copy - 1)

    def query(self, start, stop, default=0):
        """func of data[start, stop)"""
        start += self._size
        stop += self._size
        # Apply all the lazily stored queries
        self._update(start)
        self._update(stop - 1)
        res = default
        while start < stop:
            if start & 1:
                res = self._func(res, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res = self._func(res, self.data[stop])
            start >>= 1
            stop >>= 1
        return res

    def __repr__(self):
        return "LazySegmentTree({0})".format(self.data)


import sys

input = sys.stdin.readline
n, k = list(map(int, input().split()))
seg = LazySegmentTree([0] * (1 << 20))
for _ in range(n):
    v = int(eval(input()))
    most = seg.query(v, v + 1)
    # print(most)
    seg.add(max(0, v - k), v + k + 1, most + 1)
    # print(seg.data)
print((seg.query(0, 1 << 20)))

class SegmentTree:
    def __init__(self, data, default=0, func=max):
        """initialize the segment tree with data"""
        self._default = default
        self._func = func
        self._len = len(data)
        self._size = _size = 1 << (self._len - 1).bit_length()
        self.data = [default] * (2 * _size)
        self.data[_size : _size + self._len] = data
        for i in reversed(list(range(_size))):
            self.data[i] = func(self.data[i + i], self.data[i + i + 1])

    def __delitem__(self, idx):
        self[idx] = self._default

    def __getitem__(self, idx):
        return self.data[idx + self._size]

    def __setitem__(self, idx, value):
        idx += self._size
        self.data[idx] = value
        idx >>= 1
        while idx:
            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
            idx >>= 1

    def __len__(self):
        return self._len

    def query(self, start, stop):
        """func of data[start, stop)"""
        start += self._size
        stop += self._size
        res_left = res_right = self._default
        while start < stop:
            if start & 1:
                res_left = self._func(res_left, self.data[start])
                start += 1
            if stop & 1:
                stop -= 1
                res_right = self._func(self.data[stop], res_right)
            start >>= 1
            stop >>= 1
        return self._func(res_left, res_right)

    def __repr__(self):
        return "SegmentTree({0})".format(self.data)


import sys

input = sys.stdin.readline
n, k = list(map(int, input().split()))
seg = SegmentTree([0] * (1 << 20))
for _ in range(n):
    v = int(eval(input()))
    most = seg.query(max(0, v - k), v + k + 1)
    seg[v] = most + 1
print((seg.query(0, 1 << 20)))

-class LazySegmentTree: +class SegmentTree: -        """initialize the lazy segment tree with data""" +        """initialize the segment tree with data""" -        self._lazy = [0] * (2 * _size) +    def __delitem__(self, idx): +        self[idx] = self._default + +    def __getitem__(self, idx): +        return self.data[idx + self._size] + +    def __setitem__(self, idx, value): +        idx += self._size +        self.data[idx] = value +        idx >>= 1 +        while idx: +            self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1]) +            idx >>= 1 + -    def _push(self, idx): -        """push query on idx to its children""" -        # Let the children know of the queries -        q, self._lazy[idx] = self._lazy[idx], 0 -        if q: -            self._lazy[2 * idx] = max(self._lazy[2 * idx], q) -            self._lazy[2 * idx + 1] = max(self._lazy[2 * idx + 1], q) -            self.data[2 * idx] = max(self.data[2 * idx], q) -            self.data[2 * idx + 1] = max(self.data[2 * idx + 1], q) - -    def _update(self, idx): -        """updates the node idx to know of all queries applied to it via its ancestors""" -        for i in reversed(list(range(1, idx.bit_length()))): -            self._push(idx >> i) - -    def _build(self, idx): -        """make the changes to idx be known to its ancestors""" -        idx >>= 1 -        while idx: -            self.data[idx] = max( -                self.data[idx], self._func(self.data[2 * idx], self.data[2 * idx + 1]) -            ) -            self._push(idx) -            idx >>= 1 - -    def add(self, start, stop, value): -        """lazily add value to [start, stop)""" -        start = start_copy = start + self._size -        stop = stop_copy = stop + self._size +    def query(self, start, stop): +        """func of data[start, stop)""" +        start += self._size +        stop += self._size +        res_left = res_right = self._default -            # print('a', start, stop) -                self._lazy[start] = max(self._lazy[start], value) -                self.data[start] = max(self.data[start], value) +                res_left = self._func(res_left, self.data[start]) -                self._lazy[stop] = max(self._lazy[stop], value) -                self.data[stop] = max(self.data[stop], value) +                res_right = self._func(self.data[stop], res_right) -        # Tell all nodes above of the updated area of the updates -        self._build(start_copy) -        self._build(stop_copy - 1) - -    def query(self, start, stop, default=0): -        """func of data[start, stop)""" -        start += self._size -        stop += self._size -        # Apply all the lazily stored queries -        self._update(start) -        self._update(stop - 1) -        res = default -        while start < stop: -            if start & 1: -                res = self._func(res, self.data[start]) -                start += 1 -            if stop & 1: -                stop -= 1 -                res = self._func(res, self.data[stop]) -            start >>= 1 -            stop >>= 1 -        return res +        return self._func(res_left, res_right) -        return "LazySegmentTree({0})".format(self.data) +        return "SegmentTree({0})".format(self.data) -seg = LazySegmentTree([0] * (1 << 20)) +seg = SegmentTree([0] * (1 << 20)) -    most = seg.query(v, v + 1) -    # print(most) -    seg.add(max(0, v - k), v + k + 1, most + 1) -    # print(seg.data) +    most = seg.query(max(0, v - k), v + k + 1) +    seg[v] = most + 1