//  Created by Vignesh Manoharan

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <map>
#include <queue>
#include <stack>
#include <set>
#include <cstring>
#include <cassert>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<vi> vvi;

const int INF = 1000000000;
const ll LINF = 1e17;
const double PI =3.141592653589793238;
#pragma unused(INF,PI,LINF)
#define F(i,a,n) for(int i=(a);i<(n);i++)

template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){
    for(int i=0;i<(t).size();i++)s<<t[i]<<((i<(t).size()-1)?" ":"");return s; }
template<typename T> ostream& operator<<(ostream &s,set<T> t){for(T x:t) s<<x<<" ";return s; }
template<typename T> istream& operator>>(istream &s,vector<T> &t){
    for(int _i=0;_i<t.size();_i++) s>>t[_i];return s; }

#define pb push_back
#define mp make_pair
#define all(v) v.begin(),v.end()

struct flow_graph{
    int MAX_V,E,s,t,head,tail;
    int *cap,*to,*next,*last,*dist,*q,*now;
    flow_graph(){}
    flow_graph(int V, int MAX_E){
        MAX_V = V; E = 0;
        cap = new int[2*MAX_E], to = new int[2*MAX_E], next = new int[2*MAX_E];
        last = new int[MAX_V], q = new int[MAX_V], dist = new int[MAX_V], now = new int[MAX_V];
        fill(last,last+MAX_V,-1);
    }
    void clear(){
        fill(last,last+MAX_V,-1);
        E = 0;
    }
    void add_edge(int u, int v, int uv, int vu = 0){
        to[E] = v, cap[E] = uv, next[E] = last[u]; last[u] = E++;
        to[E] = u, cap[E] = vu, next[E] = last[v]; last[v] = E++;
    }
    bool bfs(){
        fill(dist,dist+MAX_V,-1);
        head = tail = 0;
        
        q[tail] = t; ++tail;
        dist[t] = 0;
        
        while(head<tail){
            int v = q[head]; ++head;
            
            for(int e = last[v];e!=-1;e = next[e]){
                if(cap[e^1]>0 && dist[to[e]]==-1){
                    q[tail] = to[e]; ++tail;
                    dist[to[e]] = dist[v]+1;
                }
            }
        }
        
        return dist[s]!=-1;
    }
    
    int dfs(int v, int f){
        if(v==t) return f;
        
        for(int &e = now[v];e!=-1;e = next[e]){
            if(cap[e]>0 && dist[to[e]]==dist[v]-1){
                int ret = dfs(to[e],min(f,cap[e]));
                
                if(ret>0){
                    cap[e] -= ret;
                    cap[e^1] += ret;
                    return ret;
                }
            }
        }
        
        return 0;
    }
    
    long long max_flow(int source, int sink){
        s = source; t = sink;
        long long f = 0;
        int x;
        
        while(bfs()){
            for(int i = 0;i<MAX_V;++i) now[i] = last[i];
            
            while(true){
                x = dfs(s,INF);
                if(x==0) break;
                f += x;
            }
        }
        
        return f;
    }
} G;

int main(int argc, const char * argv[]) {
#ifdef local_test
    //    input
    //    freopen("input","w",stdout);
    //    cout<<"1 \n 100 10 \n";
     freopen("input","r",stdin);
     freopen("output","w",stdout);
#endif
    int x,y,e,u,v;
    scanf("%d %d %d",&x,&y,&e);
    G=flow_graph(x+y+2,e+x+y);
    for(int i = 0;i<e;i++){
        scanf("%d %d",&u,&v);
        G.add_edge(u,x+v,1);
    }
    for(int i=0;i<x;i++){
        G.add_edge(x+y,i,1);
    }
    for(int i=0;i<y;i++){
        G.add_edge(x+i,x+y+1,1);
    }
    printf("%lld\n",G.max_flow(x+y,x+y+1));
}

Measured memory_bytes: 3368