#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
#pragma warning (disable: 4996)

int INF = 1000000000LL;

template<typename Type> class StarrySkyTree {
public:
	unsigned size_; std::vector<Type> dat1, dat2, dat;
	inline void update_(unsigned a, unsigned b, Type x, unsigned k, unsigned l, unsigned r) {
		if (r <= a || b <= l) return;
		if (a <= l && r <= b) {
			dat2[k] += x; return;
		}
		update_(a, b, x, (k << 1), l, (l + r) >> 1);
		update_(a, b, x, (k << 1) + 1, (l + r) >> 1, r);
		dat1[k] = std::max(dat1[k << 1] + dat2[k << 1], dat1[(k << 1) + 1] + dat2[(k << 1) + 1]);
	}
	inline Type query_(unsigned a, unsigned b, unsigned k, unsigned l, unsigned r) {
		if (r <= a || b <= l) return -INF;
		if (a <= l && r <= b) return dat1[k] + dat2[k];
		Type lc = query_(a, b, (k << 1), l, (l + r) >> 1);
		Type rc = query_(a, b, (k << 1) + 1, (l + r) >> 1, r);
		return std::max(lc, rc) + dat2[k];
	}
	//StarrySkyTree() : size_(0), dat(std::vector<Type>()) {};
	StarrySkyTree(int size__) {
		for (size_ = 1; size_ < size__; ) size_ <<= 1;
		dat1.resize(size_ << 1, 0);
		dat2.resize(size_ << 1, 0);
		dat.resize(size_ << 1, 0);
	}
	template<class T>
	StarrySkyTree(T begin_, T end_) {
		unsigned n = (end_ - begin_);
		for (size_ = 1; size_ < n; size_ <<= 1); dat.resize(size_ << 1, -INF);
		for (unsigned i = 0; i < n; i++) dat[i + size_] = *(begin_ + i);
		for (unsigned i = size_ - 1; i > 0; i--) dat[i] = std::max(dat[i << 1], dat[(i << 1) + 1]);
	}
	inline unsigned size() { return size_; }
	inline void add(unsigned i, Type x) {
		update_(i, i + 1, x, 1, 0, size_);
	}
	inline void add(unsigned l, unsigned r, Type x) {
		update_(l, r, x, 1, 0, size_);
	}
	inline Type query(unsigned l, unsigned r) {
		return query_(l, r, 1, 0, size_);
	}
};

int W, H, N, X[300009], Y[300009], Answer = 0;
vector<int> RX;

void solve(int pl, int pr, vector<int> M) {
	int cl = RX[pl], cr = RX[pr];

	vector<pair<int, int>> G;
	G.push_back(make_pair(0, RX[(pl + pr) / 2]));
	for (int i : M) G.push_back(make_pair(X[i], Y[i]));
	G.push_back(make_pair(W, RX[(pl + pr) / 2]));

	// 幅が 1 の場合
	if (pr - pl == 1) {
		Answer = max(Answer, 2 * (W + (cr - cl)));
		return;
	}

	// そうでない場合
	int cm = RX[(pl + pr) >> 1];
	StarrySkyTree<int> Z(G.size() + 2);
	vector<pair<int, int>> S1, S2;
	S1.push_back(make_pair(0, -INF));
	S2.push_back(make_pair(0, -INF));
	for (int i = 0; i < G.size(); i++) Z.add(i, i + 1, -G[i].first);
	Z.add(0, G.size(), cr - cl);

	for (int i = 1; i < G.size(); i++) {
		int ret = Z.query(0, i + 1);
		Answer = max(Answer, 2 * (ret + G[i].first));
		if (i == G.size() - 1) break;

		if (G[i].second < cm) {
			int val = cm - G[i].second, last = i, last2 = cm - cl;
			while (S1.size() >= 1) {
				if (S1[S1.size() - 1].second >= val) {
					Z.add(S1[S1.size() - 1].first, last, val - last2);
					last = S1[S1.size() - 1].first;
					last2 = S1[S1.size() - 1].second;
					S1.pop_back();
				}
				else {
					Z.add(S1[S1.size() - 1].first, last, val - last2);
					break;
				}
			}
			S1.push_back(make_pair(i, val));
		}
		else {
			int val = G[i].second - cm, last = i, last2 = cr - cm;
			while (S2.size() >= 1) {
				if (S2[S2.size() - 1].second >= val) {
					Z.add(S2[S2.size() - 1].first, last, val - last2);
					last = S2[S2.size() - 1].first;
					last2 = S2[S2.size() - 1].second;
					S2.pop_back();
				}
				else {
					Z.add(S2[S2.size() - 1].first, last, val - last2);
					break;
				}
			}
			S2.push_back(make_pair(i, val));
		}
	}

	vector<int> V1, V2;
	for (int i : M) {
		if (Y[i] < cm) V1.push_back(i);
		else V2.push_back(i);
	}

	if (V1.size() >= 1) solve(pl, (pl + pr) / 2, V1);
	if (V2.size() >= 1) solve((pl + pr) / 2, pr, V2);
}

int main() {
	scanf("%d%d%d", &W, &H, &N);
	for (int i = 1; i <= N; i++) { scanf("%d%d", &X[i], &Y[i]); RX.push_back(Y[i]); }
	RX.push_back(0); RX.push_back(H);
	sort(RX.begin(), RX.end());
	RX.erase(unique(RX.begin(), RX.end()), RX.end());
	vector<pair<int, int>> T;
	for (int i = 1; i <= N; i++) T.push_back(make_pair(X[i], Y[i]));
	sort(T.begin(), T.end());
	for (int i = 0; i < T.size(); i++) { X[i + 1] = T[i].first; Y[i + 1] = T[i].second; }

	vector<int> MM;
	for (int i = 1; i <= N; i++) {
		if (X[i] == 0 || X[i] == W || Y[i] == 0 || Y[i] == H) continue;
		MM.push_back(i);
	}
	if (MM.size() == 0) {
		cout << 2 * (H + W) << endl;
		return 0;
	}

	solve(0, RX.size() - 1, MM);

	cout << Answer << endl;
	return 0;
}

Measured memory_bytes: 51100