#include <bits/stdc++.h>
using namespace std;
ostream cnull(NULL);
template <class TH>
void _dbg(const char *sdbg, TH h) {
  cnull << sdbg << "=" << h << "\n";
}
template <class TH, class... TA>
void _dbg(const char *sdbg, TH h, TA... a) {
  while (*sdbg != ',') cnull << *sdbg++;
  cnull << "=" << h << ",";
  _dbg(sdbg + 1, a...);
}
const int MX = 200007;
vector<int> col[MX];
int row[MX];
int rep[MX], rnk[MX];
void init() {
  for (int i = 0; i < MX; ++i) rep[i] = i, rnk[i] = 0;
}
int Find(int x) { return rep[x] = (rep[x] == x ? x : Find(rep[x])); }
void Union(int a, int b) {
  if ((a = Find(a)) == (b = Find(b))) return;
  if (rnk[a] < rnk[b]) swap(a, b);
  rep[b] = a;
  rnk[a] = max(rnk[a], rnk[b] + 1);
}
int32_t main() {
  init();
  int n, m, q;
  scanf("%d%d%d", &n, &m, &q);
  for (int i = 1; i <= q; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    col[y].push_back(x);
    row[x] = 1;
  }
  for (int i = 1; i <= m; ++i) {
    for (int j = 0; j < ((int)(col[i]).size()) - 1; ++j) {
      Union(col[i][j], col[i][j + 1]);
    }
  }
  int cnt = 0;
  for (int i = 1; i <= n; ++i) cnt += (row[i] == 1 && rep[i] == i);
  int odp = cnt - 1;
  for (int i = 1; i <= n; ++i) odp += (row[i] == 0);
  for (int i = 1; i <= m; ++i) odp += (col[i].empty());
  printf("%d", odp);
}
