#include <cstdio>
#include <algorithm>
#include <cassert>
using namespace std;
const int MAX_PRODUCTS = 50010;
const int MAX_WIDTH = 30010;
const int MAX_STATES = 6;
const int INFINITY = 100000000;
int noProducts, width, height, distBetweenCols;
pair <int, int> products[MAX_PRODUCTS];
int minHeight[MAX_WIDTH], maxHeight[MAX_WIDTH], maxHeightDist[MAX_WIDTH];
int dp[MAX_WIDTH][MAX_STATES];
void read() {
freopen("magazin.in", "r", stdin);
scanf("%d %d %d %d", &noProducts, &width, &height, &distBetweenCols);
for (int i = 1; i <= noProducts; ++i) {
int x, y;
scanf("%d %d", &x, &y);
products[i] = make_pair(x, y);
}
}
void preprocess() {
sort(products+1, products+noProducts+1);
for (int i = 1, j = 1; i <= width; ++i) {
minHeight[i] = height+1;
maxHeight[i] = 0;
int lastHeight = 0;
while (j <= noProducts && products[j].first == i) {
minHeight[i] = min(minHeight[i], products[j].second);
maxHeight[i] = max(maxHeight[i], products[j].second);
maxHeightDist[i] = max(maxHeightDist[i], products[j].second-lastHeight);
lastHeight = products[j].second;
++j;
}
maxHeightDist[i] = max(maxHeightDist[i], height+1-lastHeight);
}
}
int countColumnPass(int prevState, int nextState) {
if ((prevState ^ nextState) & 1)
return 1;
return 2;
}
int calcTravelDistPerCol(int prevState, int nextState, int col) {
int factor = countColumnPass(prevState, nextState);
if ((prevState ^ nextState) & 1)
return factor*(height+1);
if (prevState < 4 && nextState >= 4)
return factor*(height+1);
if ((prevState >= 2 && prevState < 4) && nextState < 2)
return factor*(height+1);
if (nextState >= 2 || prevState >= 2)
return 2*((height+1) - maxHeightDist[col]);
if (nextState == 1)
return 2*maxHeight[col];
if (nextState == 0)
return 2*(height+1-minHeight[col]);
return 0;
}
int calcTravelDistBetweenCols(int nextState) {
if (nextState >= 2)
return 3;
return 1;
}
void doDP() {
const int noValidStates[MAX_STATES] = {5, 5, 5, 5, 2, 2};
const int validStates[MAX_STATES][MAX_STATES] = {
{0, 1, 2, 4, 5},
{0, 1, 3, 4, 5},
{0, 1, 2, 4, 5},
{0, 1, 3, 4, 5},
{0, 4},
{1, 5}
};
for (int i = 0; i <= width; ++i)
for (int j = 0; j < MAX_STATES; ++j)
dp[i][j] = INFINITY;
dp[0][1] = 0;
for (int i = 0; i < width; ++i)
for (int j = 0; j < MAX_STATES; ++j)
for (int k = 0; k < noValidStates[j]; ++k) {
dp[i+1][validStates[j][k]] = min(dp[i+1][validStates[j][k]], dp[i][j] +
calcTravelDistPerCol(j, validStates[j][k], i+1) + distBetweenCols *
calcTravelDistBetweenCols(validStates[j][k]));
}
}
void solve() {
preprocess();
doDP();
}
void write() {
freopen("magazin.out", "w", stdout);
printf("%d\n", dp[width][1]-distBetweenCols);
}
int main() {
read();
solve();
write();
return 0;
}