#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
// सुखदुःखे समे कृत्वा लाभालाभौ जयाजयौ॥
// ततो युद्धाय युज्यस्व नैवं पापमवाप्स्यसि॥
template <typename T, class C = std::less<T>>
using ordered_set = tree<T, null_type, C, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T, class C = std::less_equal<T>>
using ordered_multiset = tree<T, null_type, C, rb_tree_tag, tree_order_statistics_node_update>;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
// http://xorshift.di.unimi.it/splitmix64.c
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
#define rep(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
#define int long long int
#define F first
#define S second
#define pb push_back
#define si std::set <int>
#define vi std::vector <int>
#define vvi std::vector <vector <int>>
#define pii std::pair <int, int>
#define vpi std::vector <pii>
#define vpp std::vector <pair<int, pii>>
#define umii std::unordered_map <int, int, custom_hash>
#define mii std::map <int, int>
#define mpi std::map <pii, int>
#define spi std::set <pii>
#define endl "\n"
#define sz(x) ((int) x.size())
#define all(p) p.begin(), p.end()
#define double long double
#define que_max std::priority_queue <int>
#define que_min std::priority_queue <int, vi, greater<int>>
// https://stackoverflow.com/questions/2620862/using-custom-stdset-comparator
class compare{
bool operator()(pair<int,int> below,pair<int,int> above){
return above < below;
}
};
// priority_queue<pair<int,int>, vector<pair<int,int>>, compare) > pq; // custom hash for pq
#define bug(...) __f (#__VA_ARGS__, __VA_ARGS__)
template <typename T, typename S> constexpr T ifloor(const T a, const S b) { return a / b - (a % b && (a ^ b) < 0); }
template <typename T, typename S> constexpr T iceil(const T a, const S b) { return ifloor(a + b - 1, b); }
void setIO(string name = "") {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
if (!name.empty()) {
freopen((name + ".in").c_str(), "r", stdin);
freopen((name + ".out").c_str(), "w", stdout);
}
}
#define set_bits __builtin_popcountll
#define lead_zero __builtin_clzll
#define trail_zero __builtin_ctzll
int nxt() {
int x;
std::cin >> x;
return x;
}
int pow(int base, int exp) {
int res = 1;
while (exp > 0) {
if (exp & 1)
res = res * base;
base = base * base;
exp /= 2;
}
return res;
}
int pow(int base, int exp, int mod) {
int res = 1;
while (exp > 0) {
if (exp & 1)
res = (res * base) % mod;
base = (base * base) % mod;
exp /= 2;
}
return res;
}
const int mod = 1000000009;
const int N = 2e5 + 5;
//////////////////////////// PNC ////////////////////////////
vi fac, inv_fac;
void precompute_factorials(int n) {
fac.resize(n+1,1);
inv_fac.resize(n+1,1);
for (int i = 1; i <= n; i++) fac[i] = (fac[i-1]*i)%mod;
inv_fac[n] = pow(fac[n], mod-2, mod);
for (int i = n-1; i >= 0; i--) inv_fac[i] = (inv_fac[i+1]*(i+1))%mod;
}
int C(int n, int k){
if(n>=k && k>=0){
int ret = (fac[n] * inv_fac[k]) % mod;
ret = (ret * inv_fac[n-k]) % mod;
return ret;
}else{
return 0;
}
}
////////////////////////////////////////////////////////////
///////////////////////////// DSU ////////////////////////////
class DisjointSets {
private:
vector<int> parents;
vector<int> sizes;
public:
DisjointSets(int size) : parents(size), sizes(size, 1) {
for (int i = 0; i < size; i++) parents[i] = i;
}
int find(int x) { return parents[x] == x ? x : (parents[x] = find(parents[x])); }
bool unite(int x, int y) {
int x_root = find(x);
int y_root = find(y);
if (x_root == y_root) { return false; }
if (sizes[x_root] < sizes[y_root]) { swap(x_root, y_root); }
sizes[x_root] += sizes[y_root];
parents[y_root] = x_root;
return true;
}
bool connected(int x, int y) { return find(x) == find(y); }
};
///////////////////////////////////////////////////////
///////////////////////////// SEGMENT TREE ////////////////////////////
struct Node{
int val;
Node(){
val = 0;
}
Node(int p1){
val = p1;
}
void merge(Node &l, Node &r){
val = __gcd(l.val, r.val);
}
};
struct SegTree {
vector<Node> tree;
vi arr; // type may change
int n;
int s;
SegTree(int a_len, vi &a){ // change if type updated
arr = a;
n = a_len;
s = 1;
while (s < 2 * n){
s = s << 1;
}
tree.resize(s);
fill(tree.begin(), tree.end(), Node());
build(0, n - 1, 1);
}
void build(int start, int end, int index){ // Never change this
if (start == end){
tree[index] = Node(arr[start]);
return;
}
int mid = (start + end) / 2;
build(start, mid, 2 * index);
build(mid + 1, end, 2 * index + 1);
tree[index].merge(tree[2 * index], tree[2 * index + 1]);
}
Node query(int start, int end, int index, int left, int right){ // Never change this
if (start > right || end < left) return Node();
if (start >= left && end <= right) return tree[index];
int mid = (start + end) / 2;
Node l, r, ans;
l = query(start, mid, 2 * index, left, right);
r = query(mid + 1, end, 2 * index + 1, left, right);
ans.merge(l, r);
return ans;
}
Node make_query(int left, int right){
return query(0, n - 1, 1, left, right);
}
};
///////////////////////////////////////////////////////
void solve(){
int n = nxt(), d = nxt();
vi v(n);
generate(all(v), nxt);
sort(all(v));
int res = 1, l = 0;
rep(i,0,n){
while(v[i]-v[l] > d) l++;
res = (res * (i-l+1)) % mod;
}
cout << res;
}
int32_t main() {
setIO();
//std::cout<<std::fixed<<std::setprecision(0);
//set_factorial(N+1);
int t=1;
// std::cin>>t;
while(t--) solve();
}