#include <bits/stdc++.h>
using namespace std;
bool Debug;
const int mod = 1e9 + 7;
const int MAXN = 1e5 + 7;
template <typename T>
T gcd(T a, T b) {
  T t;
  while (t = a % b) a = b, b = t;
  return b;
}
template <typename T>
T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
template <typename T>
T Pow(T a, T b) {
  T ret = 1;
  for (; b; b >>= 1) {
    if (b & 1) ret = ret * 1ull * a % mod;
    a = a * 1ull * a % mod;
  }
  return ret % mod;
}
template <typename T>
void chmax(T &x, T y) {
  if (x < y) x = y;
}
template <typename T>
void chmin(T &x, T y) {
  if (x > y) x = y;
}
template <typename T>
void amod(T &x, T y) {
  x += y;
  if (x >= mod) x -= mod;
}
template <typename T>
void smod(T &x, T y) {
  x -= y;
  if (x < 0) x += mod;
}
struct IO {
  static const int S = 5 << 20;
  int c, f, sta[24], n;
  char wbuf[S], *p2, buf[S], *p1, *end, *wend;
  IO() { p1 = end = buf, p2 = wbuf, wend = p2 + S; }
  int getc() {
    return p1 == end && (end = (p1 = buf) + fread(buf, 1, S, stdin), p1 == end)
               ? EOF
               : *p1++;
  }
  template <typename T>
  void read(T &x) {
    x = 0;
    for (c = getc(), f = 1; !isdigit(c); c = getc()) (c == '-') && (f = -1);
    while (isdigit(c)) x = x * 10 + c - '0', c = getc();
    x *= f;
  }
  void get(char *s) {
    for (c = getc(); c <= 32; c = getc())
      ;
    for (c = getc(); c > 32; *s++ = c, c = getc())
      ;
    *s = 0;
  }
  void put(int x) {
    if (p2 == wend) fwrite(wbuf, 1, S, stdout), p2 = wbuf;
    *p2++ = x;
  }
  template <typename T>
  void out(T x, int y) {
    if (x < 0) put('-'), x = -x;
    for (n = 0; x || !n; sta[++n] = x % 10 + '0', x /= 10)
      ;
    while (n) put(sta[n--]);
    put(y);
  }
  void print(const char *s, int y) {
    while (*s) put(*s++);
    put(y);
  }
  ~IO() { fwrite(wbuf, 1, p2 - wbuf, stdout), p2 = wbuf; }
} io;
int n, m, q;
struct Node {
  int x, y;
} a[200005];
int fa[400005], ans, is[400005];
inline int Find(int x) { return x == fa[x] ? x : fa[x] = Find(fa[x]); }
inline void merge(int x, int y) {
  x = Find(x), y = Find(y);
  fa[x] = y;
}
int main() {
  ((io.read(n)), (io.read(m)), (io.read(q)));
  for (int i = 1; i <= n + m; ++i) fa[i] = i;
  for (int i = (1); i <= (q); ++i)
    ((io.read(a[i].x)), (io.read(a[i].y))), merge(a[i].x, a[i].y + n);
  for (int i = 1; i <= n + m; ++i) {
    is[Find(i)] = 1;
  }
  for (int i = 1; i <= n + m; ++i) ans += is[i];
  cout << ans - 1;
  return 0;
}
