#ifndef __cplusplus
    cat << EOF
#endif
#include <bits/stdc++.h>
using namespace std;

#define rep(...) overload_rep(__VA_ARGS__, rep_1, rep_0)(__VA_ARGS__)
#define rep_0(i, end) for(int i = 0; i < (end); ++i)
#define rep_1(i, fr, ba) for(int i = (fr); i <= (ba); ++i)
#define overload_rep(arg0, arg1, arg2, name, ...) name
#define all(box) box.begin(), box.end()

template <class T, class U> inline bool chmax(T& lhs, const U& rhs) { if(lhs < rhs) { lhs = rhs; return 1; } return 0; }
template <class T, class U> inline bool chmin(T& lhs, const U& rhs) { if(lhs > rhs) { lhs = rhs; return 1; } return 0; }

void debug_impl() { std::cerr << '\n'; }
template <class Head, class... Tail>
void debug_impl(Head&& head, Tail&&... tail) {
    std::cerr << ' ' << head;
    debug_impl(std::forward<Tail>(tail)...);
}

#define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define debug(...)\
    do { std::cerr << boolalpha << "[" << #__VA_ARGS__ << "]:";\
         debug_impl(__VA_ARGS__); std::cerr << noboolalpha; } while (false)
#else
#define debug(...)
#endif

typedef long long lint;
constexpr lint inf = 1ll << 60;

int N;
lint T;
lint X[100002];
lint dp[100002];

template <class Mn, class Op>
struct segment_tree {
private:

    int size;
    std::vector<Mn> node;
    const Mn unit;
    const Op oper;

public:

    segment_tree(const Mn& unit_, const Op& oper_) : 
        unit(unit_), oper(oper_) 
    { }
    segment_tree(const int& size_, const Mn& unit_, const Op& oper_) : 
        unit(unit_), oper(oper_) 
    { init(size_); }
    segment_tree(const std::vector<Mn>& node_, const Mn& unit_, const Op& oper_) : 
        unit(unit_), oper(oper_) 
    { build(node_); }

    void init(const int& size_) {
        for(size = 1; size < size_; size <<= 1);
        node.assign(size << 1, unit);
    }

    void build(const std::vector<Mn>& node_) {
        init(node_.size());
        for (int i = 0; i < node_.size(); ++i) {
            node[i + size] = node_[i];
        }
        for (int i = size - 1; i > 0; --i) {
            node[i] = oper(node[i << 1], node[i << 1 | 1]);
        }
    }

    void set_value(const int& idx, const Mn& value) {
        int i = idx + size;
        for (node[i] = value; (i >>= 1) > 0;) {
            node[i] = oper(node[i << 1], node[i << 1 | 1]);
        }
    }

    void add_value(const int& idx, const Mn& plus) {
        int i = idx + size;
        for (node[i] += plus; (i >>= 1) > 0;) {
            node[i] = oper(node[i << 1], node[i << 1 | 1]);
        }
    }

    Mn fold(const int& l, const int& r) const {
        Mn result_l = unit, result_r = unit;
        for(int tl = l + size, tr = r + size; tl < tr; tl >>= 1, tr >>= 1) {
            if (tl & 1) { result_l = oper(result_l, node[tl]); ++tl; }
            if (tr & 1) { --tr; result_r = oper(node[tr], result_r); }
        }
        return oper(result_l, result_r);
    }

    Mn operator [] (const int& idx) const {
        return node[idx + size];
    }

};

int main() {
    
    cin >> N;
    cin >> X[N + 1] >> T;
    rep(i, 1, N) cin >> X[i];

    const auto getmin = [](const lint& x, const lint& y) { return x < y ? x : y; };
    segment_tree<lint, decltype(getmin)> memo1(N + 1, inf, getmin), memo2(N + 1, inf, getmin);
    memo1.set_value(0, 0);
    memo2.set_value(0, - 2 * X[1]);

    rep(i, 1, N) {
        dp[i] = inf;
        int l = 0, r = (X[i] - X[1]) * 2 < T ? 0 : i;
        while(r - l > 1) {
            int md = (l + r) / 2;
            ((X[i] - X[md + 1]) * 2 >= T ? l : r) = md;
        }
        chmin(dp[i], memo1.fold(r, i) + T + X[i]);
        chmin(dp[i], memo2.fold(0, r) + 3 * X[i]);
        memo1.set_value(i, dp[i] - X[i]);
        memo2.set_value(i, dp[i] - 2 * X[i + 1] - X[i]);
    }
    
    cout << dp[N] + X[N + 1] - X[N] << '\n';
    return 0;

}


Measured memory_bytes: 5888