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: Time Limit Exceeded)

#include <bits/stdc++.h>
#define X first
#define Y second
#define mp make_pair
using namespace std;
typedef pair<int,int> PII;
const int INF = 4e8+10;
const int N = 300010;
int W,H,n,ans,tailL,tailR,f[N],L[N],R[N];
PII p[N],q[N];

struct Node {
	int l,r,mx,tag;
}t[N*4];
void build(int x,int l,int r){
	t[x].l=l,t[x].r=r;
	t[x].mx = -INF;
	t[x].tag = 0;
	if(l==r) return ;
	int mid = (l+r)/2;
	build(x*2,l,mid);
	build(x*2+1,mid+1,r);
}
inline void push(int x){
	if(t[x].tag<-INF) t[x].tag = -INF;
	t[x].mx+=t[x].tag;
	if(t[x].mx<-INF) t[x].mx = -INF;
	if(t[x].l<t[x].r) {
		t[x*2].tag += t[x].tag;
		t[x*2+1].tag += t[x].tag;
	}
	t[x].tag = 0;
}
void add(int x,int l,int r,int aug){
	if(t[x].l==l && t[x].r==r) {
		t[x].tag+=aug;
		return ;
	}
	push(x);
	int mid = (t[x].l+t[x].r)/2;
	if(r<=mid) add(x*2,l,r,aug) ;
	else if(l>mid) add(x*2+1,l,r,aug);
	else add(x*2,l,mid,aug),add(x*2+1,mid+1,r,aug);
	push(x*2),push(x*2+1);
	t[x].mx = max(t[x*2].mx,t[x*2+1].mx);
}
int find(int x,int l,int r){
	push(x);
	if(t[x].l==l && t[x].r==r) return t[x].mx;
	push(x*2),push(x*2+1);
	int mid = (t[x].l+t[x].r)/2;
	if(r<=mid) return find(x*2,l,r);
	else if(l>mid) return find(x*2+1,l,r);
	else return max(find(x*2,l,mid) ,find(x*2+1,mid+1,r));
}
void solve(int l,int r,int left,int right){
	//cout<<l<<' '<<r<<' '<<left<<' '<<right<<endl;
	int mid = (l+r)/2;
	if(l==r){
		if(p[l].Y>0) ans = max(ans,2*(right-left+p[l].Y));
		if(p[l].Y<H) ans = max(ans,2*(right-left+H-p[l].Y)); 
		if(p[l].X>left) ans =max(ans,2*(p[l].X-left+H));
		if(p[l].X<right) ans =max(ans,2*(right-p[l].X+H));
		return ;
	}
	int tmp = p[mid].X;
	solve(l,mid,left,p[mid+1].X);
	solve(mid+1,r,tmp,right);
	int cnt = 1;
	f[0]=1;
	q[1] = mp(p[mid].X,0);
	for(int i = l, j = mid+1;i <= mid || j <= r;){
		if(i <= mid && (j > r || p[j].Y > p[i].Y)){
			q[++cnt] = p[i];
			f[i] = cnt; 
			i++;
		} else {
			q[++cnt] = p[j];
			f[j] = cnt;
			j++;
		}
	}
	build(1,1,r-l+2);
	add(1,1,1,INF+right-left);
	tailL = tailR = 1;
	L[1] = R[1] = 0;
	
	for(int i = l, j = mid+1;i <= mid || j <= r;){
		if(i <= mid && (j > r || p[j].Y > p[i].Y)){
			ans = max(ans,2*(find(1,1,r-l+2)+p[i].Y));
			add(1,f[i],f[i],INF+right-left-p[i].Y);
			add(1,f[L[tailL]],f[i]-1,-p[i].X+left);
			while(tailL>1 && p[i].X>p[L[tailL]].X) {
				add(1,f[L[tailL-1]],f[L[tailL]]-1,-p[i].X+p[L[tailL]].X);
				add(1,f[L[tailL]],f[L[tailL]],-INF);
				tailL--; 
			}
			L[++tailL] = i;
			i++;
		} else {
			ans = max(ans,2*(find(1,1,r-l+2)+p[j].Y));
			add(1,f[j],f[j],INF+right-left-p[j].Y);
			add(1,f[R[tailR]],f[j]-1,-right+p[j].X);
			while(tailR>1 && p[j].X<p[R[tailR]].X) {
				add(1,f[R[tailR-1]],f[R[tailR]]-1,p[j].X-p[R[tailR]].X);
				add(1,f[R[tailR]],f[R[tailR]],-INF);
				tailR--; 
			}
			R[++tailR] = j;
			j++;
		}
	}
	ans = max(ans,2*(find(1,1,r-l+2)+H));
	
	//  end???
	for(int i=l;i<=r;i++) p[i]=q[i-l+2];
}

int main(){
	scanf("%d%d%d",&W,&H,&n);
	for(int i=1;i<=n;i++) scanf("%d%d",&p[i].X,&p[i].Y);
	sort(p+1,p+1+n);
	solve(1,n,0,W);
	//for(int i=1;i<=n;i++) cout<<p[i].X<<' '<<p[i].Y<<endl;
	printf("%d\n",ans);
	return 0;
}