#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <iostream>
#include <stack>
#include <vector>
#define INF 2000000000
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
const int MAXN = 300005;
int num[MAXN], X[MAXN], Y[MAXN];
int W, H, n, cnt;
struct Tree
{
    int maxNum, lazy;
}tree[MAXN << 2];
void pushUp(int rt)
{
    tree[rt].maxNum = max(tree[rt << 1].maxNum, tree[rt << 1 | 1].maxNum);
}
void pushDown(int rt)
{
    if(tree[rt].lazy)
    {
        tree[rt << 1].maxNum += tree[rt].lazy;
        tree[rt << 1].lazy += tree[rt].lazy;

        tree[rt << 1 | 1].maxNum += tree[rt].lazy;
        tree[rt << 1 | 1].lazy += tree[rt].lazy;

        tree[rt].lazy = 0;
    }
}
void buildTree(int l, int r, int rt)
{
    tree[rt].lazy = 0;
    if(l == r)
    {
        tree[rt].maxNum = W - num[l - 1];
        return;
    }
    int m = (l + r) >> 1;
    buildTree(lson);
    buildTree(rson);
    pushUp(rt);
}
void update(int ll, int rr, int add, int l, int r, int rt)
{
    if(ll > rr) return;
    if(ll <= l && r <= rr)
    {
        tree[rt].lazy += add;
        tree[rt].maxNum += add;
        return;
    }
    pushDown(rt);
    int m = (l + r) >> 1;
    if(ll <= m) update(ll, rr, add, lson);
    if(rr >  m) update(ll, rr, add, rson);
    pushUp(rt);
}
int query(int ll, int rr, int l, int r, int rt)
{
    if(ll > rr) return -INF;
    if(ll <= l && r <= rr) return tree[rt].maxNum;
    pushDown(rt);
    int res = -INF, m = (l + r) >> 1;
    if(ll <= m) res = max(res, query(ll, rr, lson));
    if(rr >  m) res = max(res, query(ll, rr, rson));
    return res;
}

int getPos(int x)
{
    return lower_bound(num, num + cnt, x) - num + 1;
}

int solve()
{
    vector<pair<int, int> > pts;
    cnt = 0;
    for(int i = 0; i < n; i++)
    {
        pts.push_back(make_pair(Y[i], X[i]));
        num[cnt++] = Y[i];
    }
    pts.push_back(make_pair(H, 0));
    sort(pts.begin(), pts.end());
    num[cnt++] = 0, num[cnt++] = H;
    sort(num, num + cnt);
    cnt = unique(num, num + cnt) - num;
    buildTree(1, cnt, 1);
    stack<pair<int, int> > up, dn;
    up.push(make_pair(0, W / 2)), dn.push(make_pair(0, W / 2));
    int res = -INF;
    for(int i = 0; i <= n; i++)
    {
        int x = pts[i].second, y = pts[i].first;
        res = max(res, y + query(1, getPos(y) - 1, 1, cnt, 1));
        //cout << x << " " << y << " " << query(1, getPos(y) - 1, 1, cnt, 1) << endl;
        if(x <= W / 2)
        {
            pair<int, int> A = make_pair(y , 0);
            while(x > up.top().second)
            {
                update(getPos(up.top().first), getPos(A.first) - 1 , A.second - x, 1, cnt, 1);
                A = up.top(); up.pop();
            }
            update(getPos(up.top().first), getPos(A.first) - 1 , A.second - x, 1, cnt, 1);
            up.push(pts[i]);
        }
        else
        {
            pair<int, int> A = make_pair(y , W);
            while(x < dn.top().second)
            {
                update(getPos(dn.top().first) , getPos(A.first) - 1 , x - A.second, 1, cnt, 1);
                A = dn.top(); dn.pop();
            }
            update(getPos(dn.top().first) , getPos(A.first) - 1 , x - A.second, 1, cnt, 1);
            dn.push(pts[i]);
        }
    }
    return res;
}

int main()
{
    scanf("%d%d%d", &W, &H, &n);
    W *= 2, H *= 2;
    for(int i = 0 ; i < n; i++)
    {
        scanf("%d%d", &X[i], &Y[i]);
        X[i] *= 2;
        Y[i] *= 2;
    }
    int ans = -INF;
    for(int k = 0; k < 2; k++)
    {
        ans = max(ans, solve());
        swap(W, H);
        for(int i = 0; i < n; i++) swap(X[i], Y[i]);
    }
    printf("%d\n", ans);
    return 0;
}


Measured memory_bytes: 18372