#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <unistd.h>


#define ll long long
#define lst(x) x.size()-1
#define ld long double
#define pr pair<ll,ll>
#define loop(i,n) for(ll i=0 ; i<n ; ++i)
#define rep(i,x,n) for(ll i=x ; i<=n ; ++i)
#define iteloop(type,data,name,it) for(type<data>::iterator it=name.begin() ;it!=name.end() ; ++it)

using namespace __gnu_pbds;
using namespace std;

template<typename T>
using os = tree<T, null_type, less<T>, rb_tree_tag,
        tree_order_statistics_node_update>;

const ll N=1e5+5,M=1e1+5,MOD=1e9+7,INF=1e18;

int pos[N],n,t,e;
ll memo[N];
ll seg[4*N],lazy[4*N];

int getMid(int st,int en){
    return (st+en)/2;
}
ll build(int st,int en,int frst){
    if(st==en){
        return seg[frst]=0;
    }
    int mid=getMid(st,en);
    return seg[frst]=min(build(st,mid,frst*2+1),build(mid+1,en,frst*2+2));
}
ll getmin(int st,int en,int qs,int qe,int frst){
    if(qs>qe)return INF;
    if(lazy[frst]){
        seg[frst]+=lazy[frst];
        if(st!=en) {
            lazy[frst * 2 + 1] += lazy[frst];
            lazy[frst * 2 + 2] += lazy[frst];
        }
        lazy[frst]=0;
    }
    if(st>qe || qs>en)return INF;
    if(st>=qs && en<=qe){
        return seg[frst];
    }
    int mid=getMid(st,en);
    return min(getmin(st,mid,qs,qe,frst*2+1),getmin(mid+1,en,qs,qe,frst*2+2));
}
void update(int st,int en,int qs,int qe,ll val,int frst){
    if(lazy[frst]){
        seg[frst]+=lazy[frst];
        if(st!=en) {
            lazy[frst * 2 + 1] += lazy[frst];
            lazy[frst * 2 + 2] += lazy[frst];
        }
        lazy[frst]=0;
    }
    if(st>qe || en<qs)return;
    if(st<=qs && en>=qe){
        lazy[frst]+=val;
        return ;
    }
    int mid=getMid(st,en);
    update(st,mid,qs,qe,val,frst*2+1);
    update(mid+1,en,qs,qe,val,frst*2+2);
    seg[frst]=min(seg[frst*2+1],seg[frst*2+2]);
}

ll seg2[4*N];

ll build2(int st,int en,int frst){
    if(st==en){
        return seg2[frst]=0;
    }
    int mid=getMid(st,en);
    return seg2[frst]=min(build2(st,mid,frst*2+1),build2(mid+1,en,frst*2+2));
}
ll getmin2(int st,int en,int qs,int qe,int frst){
    if(qs>qe)return INF;
    if(st>qe || qs>en)return INF;
    if(st>=qs && en<=qe){
        return seg2[frst];
    }
    int mid=getMid(st,en);
    return min(getmin2(st,mid,qs,qe,frst*2+1),getmin2(mid+1,en,qs,qe,frst*2+2));
}
ll update(int st,int en,int indexToUpdate,ll val,int frst){
    if(st>indexToUpdate || en<indexToUpdate)return seg2[frst];
    if(st==en){
        return seg2[frst]=val;
    }
    int mid=getMid(st,en);
    return seg2[frst]=min(update(st,mid,indexToUpdate,val,frst*2+1),
                          update(mid+1,en,indexToUpdate,val,frst*2+2));
}
int main(){
    cin.sync_with_stdio(false), cin.tie(0) , cout.tie(0);
#ifndef ONLINE_JUDGE
  //  freopen("in.txt", "rt" , stdin);
    // freopen("in.txt", "wt" , stdout);
#endif // ONLINE_JUDGE
    cin>>n>>e>>t;
    loop(i,n){
        cin>>pos[i];
    }
    memo[0]=t;

    build2(0,n-1,0);
    build(0,n-1,0);

    update(0,n-1,0,t,0);
    update(0,n-1,0,0,t,0);

    rep(i,1,n-1){
        int st=0,en=i-1;
        while(st<=en){
            int mid=getMid(st,en);
            if(pos[i]-pos[mid+1]>t){
                st=mid+1;
            }else{
                en=mid-1;
            }
        }
     //   cout<<st<<endl;
        memo[i]=getmin(0,n-1,0,st-1,0);

     //   cout<<i<<" "<<memo[i]<<endl;

        // to decide if it's better to return to the begining
        memo[i]=min(memo[i],(ll)max(t,2*(pos[i]-pos[0])));
       // cout<<i<<" "<<memo[i]<<endl;
        memo[i]=min(memo[i],getmin2(0,n-1,st,i-1,0)+t);
        memo[i]=min(memo[i],t+memo[i-1]);
       // cout<<i<<" "<<memo[i]<<endl;

        update(0,n-1,0,i-1,2*(pos[i+1]-pos[i]),0);
        update(0,n-1,i,i,memo[i],0);
        update(0,n-1,i,memo[i],0);

    }

    cout<<memo[n-1]+e<<endl;
}