#include <bits/stdc++.h>

using namespace std;

using int64 = long long;

constexpr int64 P = 1000000007;

struct FiniteField {
 private:
  int64 x;
 public:
  FiniteField(int64 x) : x(x) {}
  FiniteField() : x(0) {}
  int64 Value() const { return x; }
  inline FiniteField operator+(FiniteField o) const {
    FiniteField r(*this); r += o; return r;
  }
  inline FiniteField operator-(FiniteField o) const {
    FiniteField r(*this); r -= o; return r;
  }
  inline FiniteField operator* (FiniteField o) const {
    FiniteField r(*this); r *= o; return r;
  }
  inline FiniteField operator/ (FiniteField o) const {
    FiniteField r(*this); r /= o; return r;
  }
  inline void operator+= (FiniteField o) { x = (x + o.x) % P; }
  inline void operator-= (FiniteField o) { x = (x + P - o.x) % P; }
  inline void operator*= (FiniteField o) { x = (x * o.x) % P; }
  void operator/=(FiniteField o) {
    int64 p = P - 2; while (p) { if (p % 2) { *this *= o; } o *= o; p /= 2; }
  }
};

// T: The type of values.
// U: The type of operators.
// Three conditions.
// - apply_op(merge(x1, x2), o) = merge(apply_op(x1, o), apply_op(x2, o))
// - apply_op(apply_op(x, o1), o2) = apply_op(x, merge_op(o1, o2))
// - apply_op(x, empty_op) = x
// Verified: AOJ-DSL2F, AOJ-DSL2G, AOJ-DSL2H, AOJ-DSL2I
template<typename T, typename U>
class LazyPropagationSegmentTree {
 private:
  function<T(T, T)> merge_fn;
  T empty_value;
  function<U(U, U)> op_merge_fn;
  U empty_op;
  function<T(T, U)> apply_op_fn;
  int num_nodes;
  vector<T> nodes;
  vector<U> op_nodes;

  void DoLazyPropagation(int node_index) {
   if (op_nodes[node_index] != empty_op) {
      nodes[node_index] = apply_op_fn(nodes[node_index], op_nodes[node_index]);
      if (node_index < num_nodes / 2) {
        op_nodes[2 * node_index] =
            op_merge_fn(op_nodes[2 * node_index], op_nodes[node_index]);
        op_nodes[2 * node_index + 1] =
            op_merge_fn(op_nodes[2 * node_index + 1], op_nodes[node_index]);
      }
      op_nodes[node_index] = empty_op;
    }
  }

  void ApplyOpRangeInternal(
      int node_index, int node_l, int node_r, int l, int r, U op) {
    DoLazyPropagation(node_index);

    if (node_r <= l || r <= node_l) return;

    if (l <= node_l && node_r <= r) {
      op_nodes[node_index] = op;
      DoLazyPropagation(node_index);
      return;
    }
    int node_m = (node_l + node_r) / 2;
    ApplyOpRangeInternal(2 * node_index, node_l, node_m, l, r, op);
    ApplyOpRangeInternal(2 * node_index + 1, node_m, node_r, l, r, op);
    nodes[node_index] =
        merge_fn(nodes[2 * node_index], nodes[2 * node_index + 1]);
  }

  T GetRangeInternal(
      int node_index, int node_l, int node_r, int l, int r) {
    DoLazyPropagation(node_index);

    if (node_r <= l || r <= node_l) return empty_value;

    if (l <= node_l && node_r <= r) {
      return nodes[node_index];
    }

    int node_m = (node_l + node_r) / 2;
    return merge_fn(
        GetRangeInternal(2 * node_index, node_l, node_m, l, r),
        GetRangeInternal(2 * node_index + 1, node_m, node_r, l, r));
  }

 public:
  LazyPropagationSegmentTree(
      function<T(T, T)> merge_fn, T empty_value,
      function<U(U, U)> op_merge_fn, U empty_op,
      function<T(T, U)> apply_op_fn, vector<T> values) :
          merge_fn(merge_fn), empty_value(empty_value),
          op_merge_fn(op_merge_fn), empty_op(empty_op),
          apply_op_fn(apply_op_fn) {
    int n = values.size();
    num_nodes = 1;
    while (num_nodes < n) num_nodes *= 2;
    num_nodes *= 2;
    nodes = vector<T>(num_nodes, empty_value);
    op_nodes = vector<U>(num_nodes, empty_op);
    for (int i = 0; i < values.size(); ++i) {
      nodes[num_nodes / 2 + i] = values[i];
    }
    for (int i = num_nodes / 2 - 1; i >= 1; i--) {
      nodes[i] = merge_fn(nodes[2 * i], nodes[2 * i + 1]);
    }
  }

  // Applies the operator to the range [l, r).
  void ApplyOpRange(int l, int r, U op) {
    return ApplyOpRangeInternal(1, 0, num_nodes / 2, l, r, op);
  }

  T GetRange(int l, int r) {
    return GetRangeInternal(1, 0, num_nodes / 2, l, r);
  }
  
  T Get(int i) { return GetRange(i, i + 1); }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  int n;
  cin >> n;
  int64 a_diff, b_diff;
  cin >> a_diff >> b_diff;

  vector<int64> xs(n);
  for (int i = 0; i < n; i++) cin >> xs[i];

  using NodeValue = pair<FiniteField, int>;
  function<NodeValue(NodeValue, NodeValue)> merge_fn =
      [](NodeValue x, NodeValue y) -> NodeValue {
    return make_pair(x.first + y.first, x.second + y.second);
  };
  pair<FiniteField, int> empty_value = make_pair(0, 0);
  int64 empty_op = INT64_MIN;
  function<int64(int64, int64)> op_merge_fn =
      [empty_op](int64 x, int64 y) -> int64 {
    if (x == empty_op && y == empty_op) return empty_op;
    if (x == empty_op) return y;
    if (y == empty_op) return x;
    return y;
  };
  function<NodeValue(NodeValue, int64)> apply_op_fn =
      [empty_op](NodeValue x, int64 op) -> NodeValue {
    if (op == empty_op) return x;
    return make_pair(FiniteField(op) * x.second, x.second);
  };

  LazyPropagationSegmentTree<NodeValue, int64> a_tree(
      merge_fn, empty_value, op_merge_fn, empty_op, apply_op_fn,
      vector<NodeValue>(n, make_pair(0, 1)));
  LazyPropagationSegmentTree<NodeValue, int64> b_tree(
      merge_fn, empty_value, op_merge_fn, empty_op, apply_op_fn,
      vector<NodeValue>(n, make_pair(0LL, 1)));

  // i = 0
  a_tree.ApplyOpRange(0, 1, 1);
  b_tree.ApplyOpRange(0, 1, 1);

  for (int i = 1; i < n; i++) {
    int j1 = distance(
        xs.begin(),
        upper_bound(xs.begin(), xs.end(), xs[i] - a_diff));
    int j2 = distance(
        xs.begin(),
        upper_bound(xs.begin(), xs.end(), xs[i] - b_diff));
    
    FiniteField sum1 = b_tree.GetRange(0, j1 + 1).first;
    FiniteField sum2 = a_tree.GetRange(0, j2 + 1).first;
    
    a_tree.ApplyOpRange(i, i + 1, sum1.Value());
    b_tree.ApplyOpRange(i, i + 1, sum2.Value());

    if (i > j1) {
      a_tree.ApplyOpRange(0, i, 0);
    }
    if (i > j2) {
      b_tree.ApplyOpRange(0, i, 0);
    }
  }
  FiniteField a_sum = a_tree.GetRange(0, n).first;
  FiniteField b_sum = b_tree.GetRange(0, n).first;
  FiniteField sum = a_sum + b_sum;
  cout << sum.Value() << endl;
}

Measured memory_bytes: 14956