#include<deque>
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...) do {} while (0)
#endif
#include<cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}

int W, H;
int N;
pair<int, int> P[300011];
char S[300011];

struct CmpX {
    bool operator()(int i, int j) const {
	return P[i].first < P[j].first;
    }
} cmpX;
struct CmpY {
    bool operator()(int i, int j) const {
	return P[i].second < P[j].second;
    }
} cmpY;

int ans;

struct Data {
    int x, d, u;
    Data(int x_, int d_, int u_) {
	x = x_;
	d = d_;
	u = u_;
    }
};

int eval(const Data &a, const Data &b) {
    return abs(a.x - b.x) + min(a.u, b.u) - max(a.d, b.d);
}

void update(const vector<Data> &left, const vector<Data> &right) {
    int pos = 0;
//    REP (i, left.size()) {
//	while (pos < (int)right.size() && (right[pos].d < left[i].d || left[i].u < right[pos].u)) {
//	    pos++;
//	}
//	if (pos < (int)right.size()) {
//	    amax(ans, eval(left[i], right[pos]));
//	}
//    }

    pos = 0;
    REP (i, left.size()) {
	while (pos < (int)right.size() && (right[pos].d <= left[i].d && left[i].u <= right[pos].u)) {
	    pos++;
	}
	if (pos) {
	    amax(ans, eval(left[i], right[pos-1]));
	}
    }

    pos = 0;
    deque<Data> dq;
    REP (i, left.size()) {
	while (!dq.empty() && dq.front().d <= left[i].d) dq.pop_front();

	while (pos < (int)right.size() && left[i].u <= right[pos].u) {
	    if (right[pos].d <= left[i].d) {
	    } else {
		while (!dq.empty() && eval(left[i], dq.back()) <= eval(left[i], right[pos])) {
		    amax(ans, eval(left[i], dq.back()));
		    dq.pop_back();
		}
		amax(ans, eval(left[i], right[pos]));
		dq.push_back(right[pos]);
	    }
	    pos++;
	}

	if (!dq.empty()) {
	    amax(ans, eval(left[i], dq.front()));
	}
    }
}

void rec(const VI &xord, const VI &yord, int low, int high) {
    int n = xord.size();

    if (n == 1) {
	int x = P[yord[0]].first;
	int y = P[yord[0]].second;
	amax(ans, W + (high - y));
	amax(ans, W + (y - low));
	amax(ans, x + (high - low));
	amax(ans, (W - x) + (high - low));
	return;
    }

    int middle = P[yord[n/2]].second-1;
    int down = low, up = high;

    vector<Data> left, right;

    for (int i=n; i--;) if (P[xord[i]].first < W/2) {
	int y = P[xord[i]].second;
	if (down < y && y < up) {
	    left.emplace_back(P[xord[i]].first, down, up);
	    if (y < middle) down = y;
	    else up = y;
	}
    }
    left.emplace_back(0, down, up);

    down = low; up = high;
    REP (i, n) if (W/2 <= P[xord[i]].first) {
	int y = P[xord[i]].second;
	if (down < y && y < up) {
	    right.emplace_back(P[xord[i]].first, down, up);
	    if (y < middle) down = y;
	    else up = y;
	}
    }
    right.emplace_back(W, down, up);

    update(left, right);
    update(right, left);

    VI dxord, dyord, uxord, uyord;
    REP (i, n) {
	int y = P[yord[i]].second;
	if (y < middle) { S[yord[i]] = 'D'; dyord.push_back(yord[i]); }
	else { S[yord[i]] = 'U'; uyord.push_back(yord[i]); }
    }
    REP (i, n) {
	if (S[xord[i]] == 'D') dxord.push_back(xord[i]);
	else uxord.push_back(xord[i]);
    }
    rec(dxord, dyord, low, middle);
    rec(uxord, uyord, middle, high);
}

void solve() {
    VI xord(N), yord(N);
    REP (i, N) xord[i] = yord[i] = i;
    sort(xord.begin(), xord.end(), cmpX);
    sort(yord.begin(), yord.end(), cmpY);
    rec(xord, yord, 0, H);
}

void MAIN() {
    scanf("%d%d%d", &W, &H, &N);
    H *= 2;
    W *= 2;
    REP (i, N) {
	scanf("%d%d", &P[i].first, &P[i].second);
	P[i].first *= 2;
	P[i].second *= 2;
    }

    solve();
    swap(H, W);
    REP (i, N) swap(P[i].first, P[i].second);
    solve();
    printf("%d\n", ans);
}

int main() {
    int TC = 1;
//    scanf("%d", &TC);
    REP (tc, TC) MAIN();
    return 0;
}



Measured memory_bytes: 22696