#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cstring>
#include <math.h>
using namespace std;


#define int long long
const int  N = 200005;

int h, w, m, seg[4 * N];
vector<int> row[N], col[N];

void upd(int idx, int start, int end, int id) {
    if (start > end || end < id || start > id) {
        return;
    }
    else if (start == end) {
        seg[idx] = min(seg[idx] + 1, 1LL);
    }
    else {
        int mid = (start + end) / 2;
        upd(2 * idx + 1, start, mid, id);
        upd(2 * idx + 2, mid + 1, end, id);
        seg[idx] = seg[2 * idx + 1] + seg[2 * idx + 2];
    }
}


int get(int idx, int start, int end, int l, int r) {
    if (start > end || end < l || start > r) {
        return 0;
    }
    else if (start >= l && end <= r) {
        return seg[idx];
    }
    else {
        int mid = (start + end) / 2;
        int x = get(2 * idx + 1, start, mid, l, r);
        int y = get(2 * idx + 2, mid + 1, end, l, r);
        return x + y;
    }
}


int32_t main(int32_t argc, char const *argv[]) {
    cin >> h >> w >> m;
    for (int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        row[x].push_back(y);
        col[y].push_back(x);
    }   
    for (int i = 0; i < N; ++i) {
        sort(row[i].begin(), row[i].end());
        sort(col[i].begin(), col[i].end());
    }
    long long ans = 0;
    for (int i = 1; i <= h; ++i) {
        if (row[i].empty()) {
            ans += w;
        }
        else if (row[i][0] == 1) {
            break;
        }
        else {
            ans += row[i][0] - 1;
        }
    }
    for (int i = 1; i <= w; ++i) {
        if (col[i].empty()) {
            ans += h;
        }
        else if (col[i][0] == 1) {
            break;
        }
        else {
            ans += col[i][0] - 1;
        }
    }
    
    for (int i = 1; i <= h; ++i) {
        int f = 1;
        for (int &y: row[i]) {
            if (y == 1) {
                f = 0;
                break;
            }
            int sum = get(0, 1, N - 1, y, y);
            if (sum == 0) {
                upd(0, 1, N - 1, y);
            }
        }
        if (f == 0) {
            break;
        }
        int tot, r;
        if (row[i].empty()) {
            tot = r = w;
        }
        else {
            tot = r = row[i][0] - 1;
        }
        int mn, oc = 0;
        if (row[1].empty()) {
            mn = w + 1;
        }
        else {
            mn = row[1][0];
        }
        oc += max(0LL, r - mn);
        tot = tot - get(0, 1, N - 1, 1, min(mn, r)) - oc;
        ans -= tot;
    }
    cout << ans << '\n';
    return 0;
}
#include <vector>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <functional>
#include <cmath>
using namespace std;
using pos = pair<size_t, size_t>;

template<typename T, typename F>
class SegTree {
	size_t size;
	T zero;
	F f;
	vector<T> elms;

	static size_t calcSize(size_t size) {
		size_t count = size_t(1) << int(ceil(log2(size)));
		while (count < size)
			count <<= 1;
		return count + (count - 1);
	}
	static size_t parent(size_t i) { return (i - 1) / 2; }
	static size_t leftChild(size_t i) { return i * 2 + 1; }
	static size_t rightChild(size_t i) { return i * 2 + 2; }
public:
	SegTree(size_t size_, T zero_, F f_) : size(size_), zero(zero_), f(f_), elms(calcSize(size_), zero_) {}
	void SetAt(size_t i, T val) {
		i = elms.size() / 2 + i;
		while (elms[i] != val) {
			elms[i] = val;
			if (i == 0)
				break;
			i = parent(i);
			val = f(elms[leftChild(i)], elms[rightChild(i)]);
		}
	}
	T GetRangeRight(size_t i) {
		size_t a = 0, b = elms.size() / 2 + 1;
		size_t pos = 0;
		T ret = zero;
		while (i != a) {
			size_t mid = (a + b) / 2;
			if (i < mid) {
				b = mid;
				ret = f(ret, elms[rightChild(pos)]);
				pos = leftChild(pos);
			}
			else {
				a = mid;
				pos = rightChild(pos);
			}
		}
		return f(ret, elms[pos]);
	}
};

template<typename T, typename F>
SegTree<T, F> makeSegTree(size_t size, T zero, F f) {
	return SegTree<T, F>(size, zero, f);
}

int main() {
	size_t h, w, m;
	cin >> h >> w >> m;
	size_t lh = h + 1, lw = w + 1;
	unordered_map<size_t, size_t> xs, ys;
	for (size_t i = 0; i < m; ++i) {
		size_t x, y;
		cin >> x >> y;
		if (x == 1) {
			lw = min(lw, y);
			continue;
		}
		if (y == 1) {
			lh = min(lh, x);
			continue;
		}
		if (x < lh) {
			if (!xs.emplace(x, y).second)
				xs[x] = min(xs[x], y);
		}
		if (y < lw) {
			if (!ys.emplace(y, x).second)
				ys[y] = min(ys[y], x);
		}
	}
	size_t sum = h * w - (h - lh + 2) * (w - lw + 2) + 1;
	vector<pos> xss, yss;
	xss.reserve(xs.size());
	for (auto [x, y] : xs) {
		if (x >= lh)
			continue;
		if (y >= lw)
			sum -= w - y + 1;
		else
			xss.emplace_back(x, y);
	}
	xs.clear();
	yss.reserve(ys.size());
	for (auto [y, x] : ys) {
		if (y >= lw)
			continue;
		if (x >= lh)
			sum -= h - x + 1;
		else
			yss.emplace_back(x, y);
	}
	ys.clear();
	sum -= (w - lw + 1) * xss.size();
	sum -= (h - lh + 1) * yss.size();
	sort(xss.begin(), xss.end());
	sort(yss.begin(), yss.end());
	auto tree = makeSegTree(w, size_t(), plus<size_t>());
	auto last = yss.begin();
	for (auto& e : xss) {
		for (; last != yss.end() && last->first <= e.first; ++last)
			tree.SetAt(last->second - 1, 1);
		sum -= tree.GetRangeRight(e.second - 1);
	}
	cout << sum << endl;
}
