// Slower C++ solution:
#include<bits/stdc++.h>

using namespace std;



typedef long long int ll;

typedef pair<int, int> pi;

typedef vector<int> vi;

typedef vector<ll> vl;

typedef vector<vi> vvi;

typedef vector<vl> vvl;

#define all(x) (x).begin(), (x).end()

#define endl "\n"

#define pb push_back

#define mp make_pair

#define F first

#define S second

#define ar array

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

const ll mod = 1e9 + 7;

const ll inf = 2e9 + 5;

double PI = 3.14159265358979323846;



const int mxn = 3e5 + 7;

int n, m, k;

vi bombs_in_row[mxn];

vi col(mxn, 0);

multiset<int> best;



void update(int pos, int x) {

    best.erase(best.find(col[pos]));

    col[pos] += x;

    best.insert(col[pos]);

}



void solve() {



    cin >> n >> m >> k;

    for (int i = 0; i < m; i++) {

        best.insert(0);

    }



    for (int i = 0; i < k; i++) {

        int x, y;

        cin >> x >> y;

        --x;--y;

        bombs_in_row[x].pb(y);

        update(y,1);

    }

    int ans = 0;

    for(int i = 0;i < n;i++){

        int total = bombs_in_row[i].size();

        for(int y : bombs_in_row[i]){

            update(y,-1);

        }

        if(best.size()){

            total += *best.rbegin();

        }

        ans = max(ans, total);

        for(int y : bombs_in_row[i]){

            update(y,1);

        }

    }

    cout << ans << endl;



}



int32_t main()

{

    IOS

    // int T; cin >> T; while (T--)

    solve();

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 2.561008692062961x):
#include<bits/stdc++.h>

using namespace std;



typedef long long int ll;

typedef pair<int, int> pi;

typedef vector<int> vi;

typedef vector<ll> vl;

typedef vector<vi> vvi;

typedef vector<vl> vvl;

#define all(x) (x).begin(), (x).end()

#define endl "\n"

#define pb push_back

#define mp make_pair

#define F first

#define S second

#define ar array

#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

const ll mod = 1e9 + 7;

const ll inf = 2e9 + 5;

double PI = 3.14159265358979323846;



const int mxn = 3e5 + 7;

vi row(mxn, 0);

vi col(mxn, 0);



void solve() {



    int n, m, k;

    cin >> n >> m >> k;

    vector<pi> targets;

    for (int i = 0; i < k; i++) {

        int x, y;

        cin >> x >> y;

        targets.pb({x, y});

        row[x]++; col[y]++;

    }

    int ans = 0;

    int R, C;

    R = C = 0;

    for (int i = 0; i < mxn; i++) {

        R = max(R, row[i]);

        C = max(C, col[i]);

    }

    int nR, nC;

    nR = nC = 0;

    for (int i = 0; i < mxn; i++) {

        if (row[i] == R)nR++;

        if (col[i] == C)nC++;

    }

    ans = R + C;

    /*

    *

    *

    *

    *

    Now the answer is R+C unless there is an target at (i,j)

    coz we are counting it twice

    what we can do is if we find some (i,j) where row[i] = R and

    col[j] = C and there is no target at (i,j);

    To check if there exists such (i,j) count all the possible (i,j)

    where there is a target and row[i] = R and col[j] = C and if that is 

    less than nR*nC then it exits and ans remain same or else ans = ans-1

    *

    *

    *

    *

    */



    int cnt = 0;

    for(auto p : targets){

        if(row[p.F] == R and col[p.S] == C){

            ++cnt;

        }

    }

    if(cnt == nR*nC){

        ans -= 1;

    }

    cout << ans << endl;



}



int32_t main()

{

    IOS

    // int T; cin >> T; while (T--)

    solve();

    return 0;

}