#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <ctime>
#include <cassert>
#include <complex>
#include <string>
#include <cstring>
#include <chrono>
#include <random>
#include <bitset>
#define ll long long int
#define inf 1000000000000
#define mod 1000000007
#define tc(t) int t; cin >> t; while (t--)
#define all(v) v.begin(),v.end()
#define sz(x) (int)x.size()
#define F first
#define S second
#define ps(x,y)   fixed<<setprecision(y)<<x
using namespace std;

struct segtree {

	vector<int> node;
	int size;
	void init(int n) {

		size = 1;
		while (size < n)size *= 2;
		node.assign(2 * size, 0ll);
	}
	void build(vector<int>&a , int x, int lx, int rx) {

		if (rx - lx == 1) {
			if (lx < (int)a.size()) {
				node[x] = a[lx];
			}
			return;
		}
		int m = (lx + rx) / 2;
		build(a, 2 * x + 1, lx, m);
		build(a, 2 * x + 2, m, rx);
		node[x] = node[2 * x + 1] + node[2 * x + 2];
	}
	void build(vector<int>&a) {
		build(a, 0, 0, size);

	}
	void set(int i, int v, int x, int lx, int rx)
	{
		if (rx - lx == 1) {

			node[x] = v;
			return;
		}
		int m = (lx + rx) / 2;
		if (i < m) {

			set(i, v, 2 * x + 1, lx, m);
		}
		else {
			set(i, v, 2 * x + 2, m, rx);
		}
		node[x] = node[2 * x + 1] + node[2 * x + 2];
	}

	void set(int i, int v) {

		set(i, v, 0, 0, size);
	}

	int get(int l, int r, int x, int lx, int rx) {

		if (lx >= r || l >= rx)return 0;
		if (lx >= l && rx <= r )return node[x];

		int m = (lx + rx) / 2;
		int s1 = get(l, r, 2 * x + 1, lx, m);
		int s2 = get(l, r, 2 * x + 2, m, rx);

		return (s1 + s2);

	}

	int get(int r) {

		return get(0, r, 0, 0, size);
	}


};

void solve()
{
	int h, w, m;
	cin >> h >> w >> m;
	vector<pair<int, int>>obstacles(m);
	vector<vector<int>>by_row(h), by_col(w);
	segtree blocked_row;
	blocked_row.init(h + 2);
	for (int i = 0; i < m; i++) {
		cin >> obstacles[i].F >> obstacles[i].S;
	}
	sort(all(obstacles));
	for (auto [x, y] : obstacles) {
		--x, --y;
		by_row[x].push_back(y);
		by_col[y].push_back(x);
	}
	for (int x = 0; x < h; x++) {
		by_row[x].push_back(w);
	}
	for (int y = 0; y < w; y++) {
		by_col[y].push_back(h);
	}
	int reachable_rows = by_col[0][0];
	int reachable_cols = by_row[0][0];

	ll ans = 0;
	for (int x = 0; x < reachable_rows; x++) {
		ans += by_row[x][0];
	}

	for (int y = 1; y < reachable_cols; y++) {
		int height = by_col[y][0];

		ans += max(0LL, height * 1LL - reachable_rows * 1LL);
		ans += blocked_row.get(min(height, reachable_rows));
		for (auto x : by_col[y]) {
			blocked_row.set(x, 1);
		}
	}
	cout << ans << endl;


}
int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	solve();
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef vector<int> VI;
#define MP make_pair
#define PB push_back
#define X first
#define Y second
 
#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); --i)
#define ALL(a) a.begin(), a.end()
#define SZ(a) (int)((a).size())
#define FILL(a, value) memset(a, value, sizeof(a))
#define debug(a) cerr << #a << " = " << a << endl;
 
template<typename T> void setmax(T& x, T y) {x = max(x, y);}
template<typename T> void setmin(T& x, T y) {x = min(x, y);}
 
const double PI = acos(-1.0);
const int INF = 1e9 + 47;
const LL LINF = 1LL * INF * INF;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

VI g[1 << 19];
int cnt[1 << 19];
int u[1 << 19];
int m = 0;
int us = 0;

void dfs(int v)
{
	m += SZ(g[v]);
	u[v] = 1;
	us++;
	for(int to : g[v])
		if(!u[to])
			dfs(to);
}


int main()
{
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n;
	cin >> n;
	VI a(n), b(n);
	FOR(i, 0, n)
	{
		cin >> a[i] >> b[i];
		cnt[a[i]]++;
		cnt[b[i]]++;
		g[a[i]].PB(b[i]);
		g[b[i]].PB(a[i]);
	}
	int ans = 0;
	FOR(i, 1, 400001)
		if(cnt[i] && !u[i])
		{
			m = 0;
			us = 0;
			
			dfs(i);
			
			m /= 2;
			ans += min(m, us);
		}
	cout << ans << endl;
	cerr << "Time elapsed: " << clock() / (double)CLOCKS_PER_SEC << endl;
	return 0;
}
 
