#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <stack>
#include <vector>
#define uset unordered_set
#define ll long long
#define pll pair<ll,ll>
using namespace std;
ll n, m;
vector<pll> susedi = { pll(-1,0),pll(1,0),pll(0,-1),pll(0,1) };
struct pair_hash {
	inline size_t operator()(const pll& v) const {
		return v.first * 31 + v.second;
	}
};
uset<pll,pair_hash> prazna_polja;
bool je_validno_polje(pll 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(pll pocetno_polje)
{
	stack<pll> za_posecivanje;
	za_posecivanje.push(pocetno_polje);
	while (!za_posecivanje.empty())
	{
		pll tr_polje = za_posecivanje.top();
		prazna_polja.erase(tr_polje);
		za_posecivanje.pop();
		for (pll delta_sused: susedi)
		{
			pll sused = pll(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(pll(i,j));
		}
	}
	for (size_t i = 0; i < br_crnih; i++)
	{
		pll 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;
}