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 (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N	300000
#define INF	0x3f3f3f3f

int max(int a, int b) { return a > b ? a : b; }

int xx[N], yy[N], yy_[N];

int compare_x(const void *a, const void *b) {
	int i = *(int *) a;
	int j = *(int *) b;

	return xx[i] - xx[j];
}

int compare_y(const void *a, const void *b) {
	int i = *(int *) a;
	int j = *(int *) b;

	return yy[i] - yy[j];
}

int n;

void update(int *ft, int i, int x) {
	while (i < n) {
		ft[i] = max(ft[i], x);
		i |= i + 1;
	}
}

int query(int *ft, int i) {
	int x = -INF;

	while (i >= 0) {
		x = max(x, ft[i]);
		i &= i + 1, i--;
	}
	return x;
}

void clear(int *ft, int i) {
	while (i < n) {
		ft[i] = -INF;
		i |= i + 1;
	}
}

int ii[N], jj[N], x_, y_, ans;

void merge(int *ii, int l, int m, int r) {
	int h1 = l, h2 = m, h = l;

	while (h1 < m && h2 < r)
		jj[h++] = yy[ii[h1]] < yy[ii[h2]] ? ii[h1++] : ii[h2++];
	while (h1 < m)
		jj[h++] = ii[h1++];
	while (h2 < r)
		jj[h++] = ii[h2++];
	memcpy(ii + l, jj + l, (r - l) * sizeof *jj);
}

int ll[N], rr[N];

int compare_l(const void *a, const void *b) {
	int i = *(int *) a;
	int j = *(int *) b;

	return ll[i] - ll[j];
}

int ft1[N], ft2[N];

void solve(int *ii, int l, int r) {
	static int qu[N], ii1[N], ii2[N];
	int m, h, h1, h2, cnt;

	if (r - l == 1)
		return;
	m = (l + r) / 2;
	solve(ii, l, m);
	solve(ii, m, r);
	cnt = 0;
	for (h = l; h < m; h++) {
		int i = ii[h];

		while (cnt && xx[qu[cnt - 1]] < xx[i])
			cnt--;
		ll[i] = cnt ? yy[qu[cnt - 1]] : -1;
		qu[cnt++] = i;
	}
	cnt = 0;
	for (h = m - 1; h >= l; h--) {
		int i = ii[h];

		while (cnt && xx[qu[cnt - 1]] < xx[i])
			cnt--;
		rr[i] = cnt ? yy[qu[cnt - 1]] : n;
		qu[cnt++] = i;
	}
	cnt = 0;
	for (h = m; h < r; h++) {
		int i = ii[h];

		while (cnt && xx[qu[cnt - 1]] > xx[i])
			cnt--;
		ll[i] = cnt ? yy[qu[cnt - 1]] : -1;
		qu[cnt++] = i;
	}
	cnt = 0;
	for (h = r - 1; h >= m; h--) {
		int i = ii[h];

		while (cnt && xx[qu[cnt - 1]] > xx[i])
			cnt--;
		rr[i] = cnt ? yy[qu[cnt - 1]] : n;
		qu[cnt++] = i;
	}
	for (h = l; h < m; h++)
		ii1[h - l] = ii[h];
	for (h = m; h < r; h++)
		ii2[h - m] = ii[h];
	qsort(ii1, m - l, sizeof *ii1, compare_l);
	qsort(ii2, r - m, sizeof *ii2, compare_l);
	for (h1 = 0, h2 = 0; h1 < m - l; h1++) {
		int i1, i2, x1, l1, r1;

		i1 = ii1[h1], x1 = xx[i1], l1 = ll[i1], r1 = rr[i1];
		while (h2 < r - m && ll[i2 = ii2[h2]] <= l1) {
			int x2 = xx[i2], r2 = rr[i2];

			update(ft1, r2, x2 + (r2 == n ? y_ : yy_[r2])), update(ft2, n - r2, x2);
			h2++;
		}
		ans = max(ans, max(query(ft1, r1) - x1 - (l1 == -1 ? 0 : yy_[l1]), query(ft2, n - r1) - x1 + (r1 == n ? y_ : yy_[r1]) - (l1 == -1 ? 0 : yy_[l1])));
	}
	for (h2 = 0; h2 < r - m; h2++) {
		int i2 = ii2[h2], r2 = rr[i2];

		clear(ft1, r2), clear(ft2, n - r2);
	}
	for (h2 = 0, h1 = 0; h2 < r - m; h2++) {
		int i1, i2, x2, l2, r2;

		i2 = ii2[h2], x2 = xx[i2], l2 = ll[i2], r2 = rr[i2];
		while (h1 < r - m && ll[i1 = ii1[h1]] <= l2) {
			int x1 = xx[i1], r1 = rr[i1];

			update(ft1, r1, -x1 + (r1 == n ? y_ : yy_[r1])), update(ft2, n - r1, -x1);
			h1++;
		}
		ans = max(ans, max(query(ft1, r2) + x2 - (l2 == -1 ? 0 : yy_[l2]), query(ft2, n - r2) + x2 + (r2 == n ? 0 : yy_[r2]) - (l2 == -1 ? 0 : yy_[l2])));
	}
	for (h1 = 0; h1 < m - l; h1++) {
		int i1 = ii1[h1], r1 = rr[i1];

		clear(ft1, r1), clear(ft2, n - r1);
	}
	merge(ii, l, m, r);
}

int main() {
	int h, i;

	scanf("%d%d%d", &x_, &y_, &n);
	for (i = 0; i < n; i++) {
		scanf("%d%d", &xx[i], &yy[i]);
		ii[i] = i;
	}
	qsort(ii, n, sizeof *ii, compare_y);
	for (h = 0; h < n; h++)
		yy_[h] = yy[ii[h]], yy[ii[h]] = h;
	ans = max(yy_[0], y_ - yy_[n - 1]);
	for (h = 1; h < n; h++)
		ans = max(ans, yy_[h] - yy_[h - 1]);
	ans += x_;
	qsort(ii, n, sizeof *ii, compare_x);
	memset(ft1, -1, n * sizeof *ft1), memset(ft2, -1, n * sizeof *ft2);
	for (h = 0; h < n; h++) {
		int y, l, r;

		i = ii[h], y = yy[i], l = query(ft1, y), r = n - 1 - query(ft2, n - 1 - y);
		ans = max(ans, xx[i] + (r == n ? y_ : yy_[r]) - (l == -1 ? 0 : yy_[l]));
		update(ft1, y, y), update(ft2, n - 1 - y, n - 1 - y);
	}
	memset(ft1, -1, n * sizeof *ft1), memset(ft2, -1, n * sizeof *ft2);
	for (h = n - 1; h >= 0; h--) {
		int y, l, r;

		i = ii[h], y = yy[i], l = query(ft1, y), r = n - 1 - query(ft2, n - 1 - y);
		ans = max(ans, x_ - xx[i] + (r == n ? y_ : yy_[r]) - (l == -1 ? 0 : yy_[l]));
		update(ft1, y, y), update(ft2, n - 1 - y, n - 1 - y);
	}
	for (i = 0; i < n; i++)
		ft1[i] = ft2[i] = -INF;
	solve(ii, 0, n);
	ans *= 2;
	printf("%d\n", ans);
	return 0;
}