#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#define FOR(i, l, r) for(int i = l; i <= r; ++i)

using namespace std;

const int inf = 1e9; 
const int N = 300010;
const int MAX = 19;

struct segment{int tag, max;} f[1 << (MAX + 1)];
int w, h, n, ans, x[N], y[N];
vector <pair <int, int> > p;
vector <int> vec;
stack <pair <int, int> > ls, rs;
int ysit(int y) {return lower_bound(vec.begin(), vec.end(), y) - vec.begin();}

void build()
{
    for(int i = 1 << MAX; i < (1 << MAX) + vec.size(); ++i) f[i].max = w - vec[i - (1 << MAX)];
    for(int i = (1 << MAX) + vec.size(); i < 1 << (MAX + 1); ++i) f[i].max = -inf;
    for(int i = (1 << MAX) - 1; i; --i) f[i].max = max(f[i << 1].max, f[i << 1 | 1].max);
}

void downtag(int h)
{
	f[h << 1].max += f[h].tag;
	f[h << 1].tag += f[h].tag;
	f[h << 1 | 1].max += f[h].tag;
	f[h << 1 | 1].tag += f[h].tag;	
	f[h].tag = 0;
}

void add(int h, int L, int R, int dep, int v)
{
    int l = h << dep, r = (h + 1) << dep;
    if (dep) downtag(h);
    if (l == L && r == R + 1)
    {
    	f[h].max += v; f[h].tag += v;
    	return;
	}
    int mid = (l + r) >> 1;
    if (R < mid) add(h << 1, L, R, dep - 1, v); else
    if (L >= mid) add(h << 1 | 1, L, R, dep - 1, v); else
    {
    	add(h << 1, L, mid - 1, dep - 1, v);
    	add(h << 1 | 1, mid, R, dep - 1, v);
	}
	f[h].max = max(f[h << 1].max, f[h << 1 | 1].max);
}

void add(int l, int r, int v)
{
    if (l > r) return;
    add(1, l + (1 << MAX), r + (1 << MAX), MAX, v);
}

int query(int h, int L, int R, int dep)
{
	int l = h << dep, r = (h + 1) << dep;
	if (dep) downtag(h);
	if (l == L && r == R + 1) return f[h].max; int mid = (l + r) >> 1;
	if (R < mid) return query(h << 1, L, R, dep - 1);
	if (L >= mid) return query(h << 1 | 1, L, R, dep - 1);
	return max(query(h << 1, L, mid - 1, dep - 1), query(h << 1 | 1, mid, R, dep - 1));	
}

int query(int l, int r)
{
    if (l > r) return -inf;
    return query(1, l + (1 << MAX), r + (1 << MAX), MAX);
}

int solve()
{
    memset(f, 0, sizeof(f));
    p.clear(); vec.clear();
    while (!ls.empty()) ls.pop();
    while (!rs.empty()) rs.pop();
    
    ls.push(make_pair(0, w / 2));
    rs.push(make_pair(0, w / 2));
    
    FOR(i, 0, n - 1) p.push_back(make_pair(y[i], x[i]));
    sort(p.begin(), p.end());
    p.push_back(make_pair(h, 0));
    
    FOR(i, 0, n - 1) vec.push_back(y[i]);
    vec.push_back(0); vec.push_back(h);
    sort(vec.begin(), vec.end());
    vec.erase(unique(vec.begin(), vec.end()), vec.end());
    
    build();
    
    int ret = 0;
    for(int i = 0; i < p.size(); ++i)
    {
        int X = p[i].second, Y = p[i].first;
        ret = max(ret, query(0, ysit(Y) - 1) + Y);
        if (X <= w / 2)
		{
            int lstx = 0, lsty = Y;
            while (!ls.empty() && ls.top().second < X)
			{
                add(ysit(ls.top().first), ysit(lsty) - 1, lstx - X);
                lstx = ls.top().second; lsty = ls.top().first;
                ls.pop();
            }
            add(ysit(ls.top().first), ysit(lsty) - 1, lstx - X);
            ls.push(make_pair(Y, X));
        }
        else
		{
            int lstx = w, lsty = Y;
            while (!rs.empty() && rs.top().second > X)
			{
                add(ysit(rs.top().first), ysit(lsty) - 1, X - lstx);
                lstx = rs.top().second; lsty = rs.top().first;
                rs.pop();
            }
            add(ysit(rs.top().first), ysit(lsty) - 1, X - lstx);
            rs.push(make_pair(Y, X));
        }
    }
    return ret;
}

int main()
{
    scanf("%d%d%d", &w, &h, &n); w *= 2; h *= 2;
    
    FOR(i, 0, n - 1)
    {
        scanf("%d%d", &x[i], &y[i]);
        x[i] *= 2; y[i] *= 2;
    }
    ans = solve(); 
	
	swap(w, h);
    FOR(i, 0, n - 1) swap(x[i], y[i]);
    ans = max(ans, solve());
    
    printf("%d\n", ans);
    return 0;
}

Measured memory_bytes: 18928