Problem:
Score : 1600 points

Problem Statement

There is a rectangle in the xy-plane, with its lower left corner at (0, 0) and its upper right corner at (W, H). Each of its sides is parallel to the x-axis or y-axis. Initially, the whole region within the rectangle is painted white.

Snuke plotted N points into the rectangle. The coordinate of the i-th (1 ≦ i ≦ N) point was (x_i, y_i).

Then, for each 1 ≦ i ≦ N, he will paint one of the following four regions black:

the region satisfying x < x_i within the rectangle

the region satisfying x > x_i within the rectangle

the region satisfying y < y_i within the rectangle

the region satisfying y > y_i within the rectangle

Find the longest possible perimeter of the white region of a rectangular shape within the rectangle after he finishes painting.

Constraints

1 ≦ W, H ≦ 10^8

1 ≦ N ≦ 3 \times 10^5

0 ≦ x_i ≦ W (1 ≦ i ≦ N)

0 ≦ y_i ≦ H (1 ≦ i ≦ N)

W, H (21:32, added), x_i and y_i are integers.

If i ≠ j, then x_i ≠ x_j and y_i ≠ y_j.

Input

The input is given from Standard Input in the following format:

W H N
x_1 y_1
x_2 y_2
:
x_N y_N

Output

Print the longest possible perimeter of the white region of a rectangular shape within the rectangle after Snuke finishes painting.

Sample Input 1

10 10 4
1 6
4 1
6 9
9 4

Sample Output 1

32

In this case, the maximum perimeter of 32 can be obtained by painting the rectangle as follows:

Sample Input 2

5 4 5
0 0
1 1
2 2
4 3
5 4

Sample Output 2

12

Sample Input 3

100 100 8
19 33
8 10
52 18
94 2
81 36
88 95
67 83
20 71

Sample Output 3

270

Sample Input 4

100000000 100000000 1
3 4

Sample Output 4

399999994

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#endif
//#pragma GCC optimize("O3")
#include <bits/stdc++.h>

using namespace std;
typedef long double ld;
typedef long long ll;
int w, h;
const int maxN = 3 * (int) 1e5 + 10;
int x[maxN], y[maxN];
int n;
int best = -1488;
int nx[maxN], ny[maxN];
int L[maxN], R[maxN];
int t[2][4 * maxN];

void upd(int tp, int v, int tl, int tr, int pos, int val) {
    if (tl == tr) {
        t[tp][v] = max(t[tp][v], val);
        return;
    }
    int tm = (tl + tr) / 2;
    if (pos <= tm) upd(tp, v + v, tl, tm, pos, val);
    else upd(tp, v + v + 1, tm + 1, tr, pos, val);
    t[tp][v] = max(t[tp][2 * v], t[tp][2 * v + 1]);
}

const int INF = (int) 1e9;

int get(int tp, int v, int tl, int tr, int l, int r) {
    if (l > r) return -INF;
    if (tl == l && tr == r) return t[tp][v];
    int tm = (tl + tr) / 2;
    return max(get(tp, 2 * v, tl, tm, l, min(r, tm)), get(tp, 2 * v + 1, tm + 1, tr, max(tm + 1, l), r));
}

int fenw[2][maxN];
int N;
void updMax(int tp, int v, int by) {
    while (v <= N) {
        fenw[tp][v] = max(fenw[tp][v], by);
        v = (v | (v - 1)) + 1;
    }
}
int getMax(int tp, int v) {
    int ans = -INF;
    while (v > 0) {
        ans = max(ans, fenw[tp][v]);
        v &= (v - 1);
    }
    return ans;
}

int idY[maxN];

int lst_fenw[maxN];
int SZ;
int QQ;
const int P = 1e7;
int evs[P];
void upd(int v, int by) {
    while (v <= SZ) {
        lst_fenw[v] = max(lst_fenw[v], by);
        evs[QQ++] = v;
        v = (v | (v - 1)) + 1;
    }
}

int get(int v) {
    int ans = -INF;
    while (v > 0) {
        ans = max(ans, lst_fenw[v]);
        v &= (v - 1);
    }
    return ans;
}

void redo() {
    for (int i = 0; i <= QQ; i++) {
        lst_fenw[evs[i]] = -INF;
    }
    QQ = 0;
}

void solve(int l, int r) {
    if (l == r) {
        best = max(best, h);
        best = max(best, w);
        return;
    }
    int mid = (l + r) / 2;
    solve(l, mid);
    solve(mid + 1, r);
    upd(1, 0);
    for (int i = mid; i >= l; i--) {
        L[i] = get(idY[i]);
        upd(idY[i], y[i]);
    }
    redo();
    upd(1, -h);
    for (int i = mid; i >= l; i--) {
        R[i] = -get(SZ + 1 - idY[i]);
        upd(SZ + 1 - idY[i], -y[i]);
    }
    redo();
    upd(1, 0);
    for (int i = mid + 1; i <= r; i++) {
        L[i] = get(idY[i]);
        upd(idY[i], y[i]);
    }
    redo();
    upd(1, -h);
    for (int i = mid + 1; i <= r; i++) {
        R[i] = -get(SZ + 1 - idY[i]);
        upd(SZ + 1 - idY[i], -y[i]);
    }
    redo();
    vector<int> allL;
    for (int i = l; i <= r; i++) {
        allL.emplace_back(L[i]);
    }
    sort(allL.begin(), allL.end());
    allL.erase(unique(allL.begin(), allL.end()), allL.end());
    vector<pair<int, int> > events;
    for (int i = l; i <= r; i++) {
        events.emplace_back(R[i], i);
    }
    sort(events.begin(), events.end());
    int sz = allL.size();
    int n = sz;
    N = n;
    for (int i = 1; i <= sz; i++) {
        for (int j = 0; j < 2; j++) {
            fenw[j][i] = -INF;
        }
    }
    for (auto it : events) {
        int he = lower_bound(allL.begin(), allL.end(), L[it.second]) - allL.begin() + 1;
        if (it.second <= mid) {
            updMax(0, N + 1 - he, it.first - L[it.second] - x[it.second]);
            updMax(1, he, it.first - x[it.second]);
        } else {
            best = max(best, x[it.second] + getMax(0, N + 1 - he));
            best = max(best, x[it.second] - L[it.second] + getMax(1, he));
        }
    }
    for (int i = 1; i <= 4 * sz; i++) {
        for (int j = 0; j < 2; j++) {
            fenw[j][i] = -INF;
        }
    }
    reverse(events.begin(), events.end());
    for (auto it : events) {
        int he = lower_bound(allL.begin(), allL.end(), L[it.second]) - allL.begin() + 1;
        if (it.second <= mid) {
            updMax(0, N + 1 - he, -L[it.second] - x[it.second]);
            updMax(1, he, -x[it.second]);
        } else {
            best = max(best, it.first + x[it.second] + getMax(0, N + 1 - he));
            best = max(best, it.first + x[it.second] - L[it.second] + getMax(1, he));
        }
    }
}

mt19937 rnd(239);
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("input.txt", "r", stdin);
    cin >> w >> h >> n;
    for (int a : {0, w}) {
        for (int b : {0, h}) {
            n++;
            x[n] = a;
            y[n] = b;
        }
    }
    vector<int> allx, ally;
    vector<int> pts;
    for (int i = 1; i <= n; i++) {
        cin >> x[i] >> y[i];
        pts.emplace_back(i);
    }
    if (rnd() & 1) {
        for (int i = 1; i <= n; i++) swap(x[i], y[i]);
        swap(w, h);
    }
    for (int step = 0; step < 2; step++) {
        sort(pts.begin(), pts.end(), [&](int a, int b) {
            return x[a] < x[b];
        });
        for (int i = 0; i < pts.size(); i++) {
            nx[i + 1] = x[pts[i]];
            ny[i + 1] = y[pts[i]];
        }
        vector < int > gg;
        for (int i = 1; i <= n; i++) {
            x[i] = nx[i];
            y[i] = ny[i];
            gg.emplace_back(y[i]);
        }
        sort(gg.begin(), gg.end());
        for (int i = 1; i <= n; i++) {
            idY[i] = lower_bound(gg.begin(), gg.end(), y[i]) - gg.begin() + 1;
        }
        SZ = gg.size();
        if (step == 0) {
            solve(1, n);
        }
        else {
            for (int i = 1; i <= n; i++) {
                solve(i, min(i + 2, n));
            }
        }
        swap(w, h);
        for (int i = 1; i <= n; i++) {
            swap(x[i], y[i]);
        }
    }
    cout << 2 * best;
    return 0;
}