// 0bd35dc5e428754fa574049b6be8efe0

#include <bits/stdc++.h>

using namespace std;

#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define fst first
#define snd second
#define SZ(u) ((int) (u).size())
#define ALL(u) (u).begin(), (u).end()

inline void proc_status()
{
	ifstream t("/proc/self/status");
	cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
}

template<typename T> inline bool chkmin(T &a, const T &b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, const T &b) { return a < b ? a = b, 1 : 0; }
template<typename T> inline T read()
{
	register T sum(0), fg(1);
	register char ch(getchar());
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') fg = -1;
	for(;  isdigit(ch); ch = getchar()) sum = sum * 10 - '0' + ch;
	return sum * fg;
}

typedef long long LL;
typedef pair<int, int> pii;

const int MAXN = (int) 3e5;

struct point
{
	int x, y;

	inline bool operator < (const point &rhs) const { return this->y < rhs.y; }

	point() { }
	point(int _x, int _y): x(_x), y(_y) { }
}a[MAXN + 5];

int n, W, H;

inline void input()
{
	W = read<int>(), H = read<int>();
	n = read<int>();
	for(int i = 1; i <= n; ++i) a[i].x = read<int>(), a[i].y = read<int>();
}

namespace SEGT
{
	const int MAX_NODE = MAXN * 4;

	int mx[MAX_NODE + 5];
	int add[MAX_NODE + 5];

	inline void push_up(int u) { mx[u] = max(mx[u << 1], mx[u << 1 | 1]); }
	inline void push_down(int u)
	{
		if(add[u])
		{
			mx[u << 1] += add[u];
			mx[u << 1 | 1] += add[u];
			add[u << 1] += add[u];
			add[u << 1 | 1] += add[u];
			add[u] = 0;
		}
	}

	inline void build(int u, int l, int r)
	{
		add[u] = 0;
		if(l == r)
		{
			mx[u] = (l >= 1 ? -a[l].y : 0) + W;
			return;
		}

		int mid = (l + r) / 2;
		build(u << 1, l, mid);
		build(u << 1 | 1, mid + 1, r);
		push_up(u);
	}

	inline void update(int u, int l, int r, int ql, int qr, int val)
	{
		if(ql > qr) return;
		if(ql <= l && r <= qr)
		{
			mx[u] += val;
			add[u] += val;
			return;
		}
		push_down(u);

		int mid = (l + r) / 2;
		if(ql <= mid) update(u << 1, l, mid, ql, qr, val);
		if(mid < qr) update(u << 1 | 1, mid + 1, r, ql, qr, val);
		push_up(u);
	}

	inline int query(int u, int l, int r, int ql, int qr)
	{
		if(ql <= l && r <= qr) return mx[u];
		push_down(u);

		int mid = (l + r) / 2, res = INT_MIN;
		if(ql <= mid) chkmax(res, query(u << 1, l, mid, ql, qr));
		if(mid < qr) chkmax(res, query(u << 1 | 1, mid + 1, r, ql, qr));
		return res;
	}
}

inline int calc()
{
	sort(a + 1, a + n + 1);
	SEGT::build(1, 0, n);

	static vector<int> mn_pos, mx_pos;
	mn_pos.clear();
	mx_pos.clear();

	mn_pos.push_back(0);
	mx_pos.push_back(0);
	int ans = 0;
	for(int i = 1; i <= n; ++i)
	{
		chkmax(ans, 2 * (a[i].y + SEGT::query(1, 0, n, 0, i - 1)));

		if(a[i].x >= W / 2)
		{
			SEGT::update(1, 0, n, mn_pos.back(), i - 1, -W);
			while(SZ(mn_pos) > 1 && a[mn_pos.back()].x >= a[i].x)
			{
				int p = mn_pos.back();
				mn_pos.pop_back();
				SEGT::update(1, 0, n, mn_pos.back(), p - 1, -a[p].x);
			}
			SEGT::update(1, 0, n, mn_pos.back(), i - 1, +a[i].x);
			mn_pos.push_back(i);
		}

		if(a[i].x <= W / 2)
		{
			SEGT::update(1, 0, n, mx_pos.back(), i - 1, +0);
			while(SZ(mx_pos) > 1 && a[mx_pos.back()].x <= a[i].x)
			{
				int p = mx_pos.back();
				mx_pos.pop_back();
				SEGT::update(1, 0, n, mx_pos.back(), p - 1, +a[p].x);
			}
			SEGT::update(1, 0, n, mx_pos.back(), i - 1, -a[i].x);
			mx_pos.push_back(i);
		}
	}
	chkmax(ans, 2 * (H + SEGT::mx[1]));
	return ans;
}

inline void solve()
{
	int ans = 0;
	chkmax(ans, calc());
	swap(W, H);
	for(int i = 1; i <= n; ++i) swap(a[i].x, a[i].y);
	chkmax(ans, calc());
	printf("%d\n", ans);
}

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("F.in", "r", stdin);
//	freopen("F.out", "w", stdout);
#endif

	input();
	solve();

	return 0;
}



Measured memory_bytes: 12924