#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <stack>
#include <vector>
#define uset unordered_set
#define pii pair<int,int>
#define ll long long
using namespace std;
int n, m;
vector<pii> susedi = { pii(-1,0),pii(1,0),pii(0,-1),pii(0,1) };
struct pair_hash {
	inline size_t operator()(const pii& v) const {
		return v.first * 31 + v.second;
	}
};
uset<pii,pair_hash> prazna_polja;
bool je_validno_polje(pii polje)
{
	if (prazna_polja.find(polje) == prazna_polja.end())
		return false;
	if (polje.second > m || polje.second < 0)
		return false;
	if (polje.first > n || polje.first < 0)
		return false;
	return true;
}
void dfs_oboji(pii pocetno_polje)
{
	stack<pii> za_posecivanje;
	za_posecivanje.push(pocetno_polje);
	while (!za_posecivanje.empty())
	{
		pii tr_polje = za_posecivanje.top();
		prazna_polja.erase(tr_polje);
		za_posecivanje.pop();
		for (pii delta_sused: susedi)
		{
			pii sused = pii(tr_polje.first + delta_sused.first, tr_polje.second + delta_sused.second);
			if (je_validno_polje(sused))
				za_posecivanje.push(sused);
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int br_crnih;
	cin >> n >> m >> br_crnih;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
		{
			prazna_polja.insert(pii(i,j));
		}
	}
	for (size_t i = 0; i < br_crnih; i++)
	{
		pii tacka;
		cin >> tacka.first >> tacka.second;
		prazna_polja.erase(tacka);
	}
	ll broj_boja = 0;
	while (prazna_polja.size() > 0)
	{
		dfs_oboji(*(prazna_polja.begin()));
		broj_boja++;
	}
	cout << broj_boja << "\n";
	return 0;
}