#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(int (i) = (s);(i) <= (e);(i)++)
#define all(x) x.begin(),x.end()
 
 
struct edge {
  int from;
  int to;
  i64 cost;
  int num;
};

struct gabow_scaling_wbm {
  i64 res;
  vector<i64> c,yd,y,mate,used;
  int n;
  int m;
  const vector<vector<edge>>& g;
  int V0;
  i64 cl(const edge& e) {
    return c[e.num] - y[e.from] - y[e.to] + (mate[e.to] == e.from ? 0 : 1);
  };
  bool eligible(const edge& e) {
    return yd[e.from] + yd[e.to] == cl(e);
  }
  bool hk_dfs(int v, vector<bool>& vis, vector<bool>& vv) {
    vis[v] = true;
    for(const auto& e : g[v]) {
      if(!eligible(e)) continue;
      if(mate[e.to] == -1 || (!vis[mate[e.to]] && hk_dfs(mate[e.to], vis, vv))) {
        mate[e.to] = v;
        used[v] = true;
        vv[e.to] = true;
        return true;
      }
    }
    return false;
  };

  bool hk() {
    bool loop = false;
    bool res = true;
    vector<bool> vv(n, false);

    {
      loop = false;



      for(int i = 0;i < V0;i++) {
        if(!used[i]) {
          vector<bool> vis(n, false);
          if(hk_dfs(i, vis, vv)) {
            loop = true;
          }
        }
      }
      res = true;
      for(int i = V0;i < n;i++) {
        if(mate[i] == -1) res = false;
      }
    }
    /*
       cout << "===" << endl;
       for(int i = V0;i < n;i++) {
       if(mate[i] != -1) {
       cout << mate[i] << "-" << i << endl;
       }
       }
       */

    for(int i = V0;i < n;i++) {
      if(vv[i]) yd[i]--;
    }
    return res;
  };

  gabow_scaling_wbm(const vector<vector<edge>>& g, int v0) : g(g) {
    this->V0 = v0;
    n = g.size();
    m = 0;
    auto MF = [&]() {
      i64 MAX = 1;
      for(int i = 0;i < n;i++) {
        for(const auto& e : g[i]) {
          m++;
          MAX = max(MAX , abs(e.cost));
        }
      }
      return MAX;
    };
    int k = (int)log2(MF()) + 1;
    vector<edge> es(m);

    for(int i = 0;i < n;i++) {
      for(const auto& e : g[i]) {
        es[e.num] = e;
      }
    }


    c.assign(m,0);
    yd.assign(n, 0);
    y.assign(n,0);
    mate.assign(n , -1);
    used.assign(n, false);




    for(int s = k - 1;s >= 0;s--) {
      //cout << "scaling" << " " << s << endl;
      for(int i = 0;i < m;i++) {
        c[i] = c[i] * 2 + (es[i].cost >= 0 ? 1 : -1) * ((abs(es[i].cost) >> s) & 1);
      }
      for(int i = 0;i < n;i++) {
        y[i] = y[i] * 2 - 1;
      }

      yd.assign(n, 0);
      mate.assign(n, -1);
      used.assign(n, false);

      int cnt = 0;

      while(!hk()) {
        vector<bool> vis(n, false);

        using P = pair<i64,i64>;

        vector<queue<int>> Q(5 * n + 1);
        int idx = 0;

        vector<i64> dd(n, 0);
        i64 DELTA = 0;

        for(int i = 0;i < V0;i++) {
          if(!used[i]) {
            for(const auto& e: g[i]) {
              auto xx = cl(e) - yd[i] - yd[e.to] + dd[i];
              if(Q.size() <= xx) continue;
              Q[xx].push(e.to);
            }
            vis[i] = true;
          }
        }

        bool freed = false;

        while(true) {
          while(idx < Q.size() && Q[idx].empty()) idx++;
          if(idx >= Q.size()) break;
          i64 D = idx;
          int w = Q[idx].front();
          Q[idx].pop();
          if(vis[w]) continue;
          if(freed && DELTA != D) break;
          vis[w] = true;
          DELTA = D;
          dd[w] = DELTA;
          if(mate[w] != -1 && !vis[mate[w]]) {
            int mm = mate[w];
            dd[mm] = DELTA;
            for(const auto& e : g[mm]) {
              if(vis[e.to]) continue;
              if(mate[e.to] == mm) continue;
              auto xx = cl(e) - yd[mm] - yd[e.to] + dd[mm];
              if(Q.size() <= xx) continue;
              Q[xx].push(e.to);
            }
            vis[mm] = true;
          }
          else if(mate[w] == -1) {
            freed = true;
          }
        }

        for(int i = 0;i < n;i++) {
          if(!vis[i]) continue;
          yd[i] = yd[i] + (DELTA - dd[i]) * (i < V0 ? 1 : -1);
        }
      }
      for(int i = 0;i < n;i++) {
        y[i] = y[i] + yd[i];
      }
    }

    i64 ans = 0;
    for(int i = 0;i < n;i++) {
      ans += y[i];
    }
    res = ans;
  }
};

int main() {
  int x,y,m;
  cin >> x >> y >> m;
  vector<vector<edge>> g(x + y + x + y);
  int idx = 0;
  for(int i = 0;i < m;i++) {
    int v,w;
    cin >> v >> w;
    g[v].push_back({v, w + x + y, -1  , idx++});
    g[w + x].push_back({w + x, v + x + y + y, -1, idx++});
  }
  for(int i = 0;i < x; i++) {
    g[i].push_back({i, i + x + y + y, 0, idx++});
  }
  for(int i = x;i < x + y;i++) {
    g[i].push_back({i, i + y, 0, idx++});
  }
  cout << -gabow_scaling_wbm(g,x + y).res / 2 << endl;
}



Measured memory_bytes: 5604