#include <bits/stdc++.h>
#define WHOLE(v) (v).begin(), (v).end()
#define REV_WHOLE(v) (v).rbegin(), (v).rend()
using i64 = int64_t;
using namespace std;
template<class F>auto recursive(F f){return[f](auto...a){return f(f,a...);};}
template<class T>using rev_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<class T>using vector2d=vector<vector<T>>;
struct fixprec{int p;fixprec(int p):p(p){}};
ostream&operator<<(ostream&o,fixprec f){return o<<fixed<<setprecision(f.p);}

/*!* [minmax_assign] *!*/
/*+* 最大値、最小値の代入 *+*/
template<class T>void max_assign(T&x,const T y){x=max(x,y);}
template<class T>void min_assign(T&x,const T y){x=min(x,y);}

/*!* [binsearch] *!*/
/*+* 二分探索 *+*/
// judge を満たすような(l,r]内の下限を求める
// l:[X] 定義域の下端
// r:[X] 定義域の上端
// judge:[F = X -> bool] 値 X を評価する関数
// lower:[bool] false にすると代わりに[l,r)内の上限を求める
// eps:[X] 終了距離

template <typename X, typename F>
X BinSearch(X l, X r, F judge, bool lower = true, X eps = 1) {
    while (r - l > eps) {
        X m = (r + l) / 2;
        if (judge(m) == lower) {
            r = m;
        } else {
            l = m;
        }
    }
    return lower ? r : l;
}

/*!* [segtree] *!*/
/*+* セグメント木 *+*/
// Tは $f : T \to T$ についてモノイドである必要がある。
// Fの型をdecltype(f)とすると高速になる。
template <typename T, typename F = function<T(T, T)>>
struct SegTree {
    int N;
    vector<T> array; 
    const F f;
    const T id;
    SegTree() {}
    // len : データ長, f : 二項演算, identity: 初期値(単位元)
    SegTree(int len, const F f, const T &id) : f(f), id(id) {
        for(N = 1; N < len; N <<= 1);
        array.reserve(2 * N - 1);
        array.assign(2 * N - 1, id);
    }
    
    // 値の更新 O(\log N)$
    // k : 添字, val : 値
    void update(int k, T val) {
        k += N;
        array[k] = val;
        while(k >>= 1) array[k] = f(array[2 * k], array[2 * k + 1]);
    }
    
    // 値の取り出し O(1)$
    // k : 添字
    T operator[] (int k) { return array[k + N]; }

    // 範囲検索 O(\log N)$
    // [L : R] の範囲について、f( [L : R] ) を求める
    T query(int l, int r) {
        T L = id, R = id;
        for(l += N, r += N, r++; l < r; l >>= 1, r >>= 1) {
            if(l & 1) L = f(L, array[l++]);
            if(r & 1) R = f(array[--r], R);
        }
        return f(L, R);
    }
};

int main() {
    const i64 INF = 1e12;
    i64 N, E, T;
    cin >> N >> E >> T;
    vector<i64> x = {0};
    for(int i = 0; i < N; i++) {
        i64 a;
        cin >> a;
        x.push_back(a);
    }
    auto f_min = [](i64 a, i64 b) -> i64 { return min(a, b); };
    vector<i64> dp(N + 1, INF);
    dp[0] = 0;
    SegTree<i64, decltype(f_min)> seg_front(N + 1, f_min, INF),
                                   seg_back(N + 1, f_min, INF);

    seg_front.update(0, -2 * x[1]);
    seg_back.update(0, 0);
    for(int k = 1; k <= N; k++) {
        int j = BinSearch<int>(-1, k, [&](int i) -> bool {
            return 2 * (x[k] - x[i + 1]) < T;
        });
        if (j > 0) {
            min_assign(dp[k], 3 * x[k] + seg_front.query(0, j - 1));
        }
        min_assign(dp[k], x[k] + T + seg_back.query(j, N));
        if(k < N) {
            seg_front.update(k, dp[k] - x[k] - 2 * x[k + 1]);
            seg_back.update(k, dp[k] - x[k]);
        }
    }
    cout << dp[N] + E - x[N] << endl;
    return 0;
}

Measured memory_bytes: 6004