#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

//BEGIN CUT HERE
//Dinic
//最大流を高速に求めることが出来ます
//二部マッチングにも使ってください
class Dinic{
public:

    //引数はありうる頂点の最大の数を入れてください
    explicit Dinic(int v):vertex(static_cast<unsigned int>(v)){
        G.resize(vertex+10);
    }

    //頂点fromからtoへの流せる量の最大がcapのとき、add_edge(int from,int to,ll cap)
    //
    //二部マッチングのときは、capは1にしてください
    //二部マッチングのとき、意図的に、与えられる頂点以外に２つ頂点を作ってください
    //それをs,tとしてsからtへの最大流を求めてください
    void add_edge(int from,int to,ll cap){
        G[from].push_back((edge){to, cap, static_cast<int>(G[to].size())});
        G[to].push_back((edge){from, 0, static_cast<int>(G[from].size() - 1)});
    }

    ll max_flow(int s,int t){//s->start , t->end
        ll flow=0;
        for(;;){
            bfs(s);
            if(level[t]<0)return flow;
            iter.clear();
            iter.resize(vertex+10,0);
            ll f;
            while((f=dfs(s,t,INF))>0)flow+=f;
        }
    }
private:
    unsigned int vertex;
    struct edge{
        int to;
        ll cap;
        int rev;
    };
    vector<vector<edge> > G;
    vector<int> level;
    vector<int> iter;
    ll INF=(ll)1e16;
    void bfs(int start){
        level.clear();
        level.resize(vertex+10,-1);
        queue<int> q;
        q.push(start);
        level[start]=0;
        while(!q.empty()){
            int now=q.front();
            q.pop();
            for(int i=0;i<(int)G[now].size();i++) {
                if(G[now][i].cap>0 && level[G[now][i].to]<0){
                    level[G[now][i].to]=level[now]+1;
                    q.push(G[now][i].to);
                }
            }
        }
    }
    ll dfs(int now,int t,ll f){
        if(now==t)return f;
        for(int &i=iter[now];i<(int)G[now].size();i++){
            edge &e=G[now][i];
            if(e.cap>0 && level[now]<level[e.to]){
                ll d=dfs(e.to,t,min(f,e.cap));
                if(d>0){
                    e.cap-=d;
                    G[e.to][e.rev].cap+=d;
                    return d;
                }
            }
        }
        return 0;
    }
};
//END CUT HERE

//検証しました!!!!
//ARC092-B 2D Plane 2N Points
/*int main(){
    int n;cin>>n;
    Dinic f(2*n);
    int s=2*n;
    int t=s+1;
    vector<pair<int,int> > aka,ao;
    for(int i=0;i<n;i++){
        int a,b;cin>>a>>b;
        aka.push_back({a,b});
        f.add_edge(s,i,1);
    }
    for(int i=0;i<n;i++){
        int a,b;cin>>a>>b;
        ao.push_back({a,b});
        f.add_edge(n+i,t,1);
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            if(aka[j].first<ao[i].first && aka[j].second<ao[i].second){
                f.add_edge(j,n+i,1);
            }
        }
    }
    cout<<f.max_flow(s,t)<<endl;
}*/
/*
int main(){
    int v,e;cin>>v>>e;
    Dinic f(v);
    for(int i=0;i<e;i++){
        int from,to,cap;cin>>from>>to>>cap;
        f.add_edge(from,to,cap);
    }
    cout<<f.max_flow(0,v-1)<<endl;
}*/

int main(){
    int x,y,e;cin>>x>>y>>e;
    Dinic d(x+y+2);
    int s=x+y+1;
    int t=s+1;
    for(int i=0;i<x;i++){
        d.add_edge(s,i,1);
    }
    for(int j=0;j<y;j++){
        d.add_edge(x+j,t,1);
    }
    for(int i=0;i<e;i++){
        int a,b;cin>>a>>b;
        d.add_edge(a,x+b,1);
    }
    cout<<d.max_flow(s,t)<<endl;
    return 0;
}


Measured memory_bytes: 3636