#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
template<class T> using vc = vector<T>;
template<class T> using vvc = vector<vector<T>>;

#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define repe(i, l, r) for (ll i = (l); i < (r); i++)
#define reper(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define repa(i,n) for (auto& i: n)

template<class T> inline bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> inline bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
void init() {cin.tie(0);ios::sync_with_stdio(false);cout << fixed << setprecision(15);}

#ifdef DEBUG
template <class T, class N> void verr(const T& a, const N& n) { rep(i, n) cerr << a[i] << " "; cerr << "\n" << flush; }
ll dbgt = 1; void err() { cerr << "passed " << dbgt++ << "\n" << flush; }
template<class H, class... T> void err(H&& h,T&&... t){ cerr<< h << (sizeof...(t)?" ":"\n") << flush; if(sizeof...(t)>0) err(forward<T>(t)...); }
#endif

const ll INF = 4e18;
const ld EPS = 1e-11;
const ld PI = acos(-1.0L);
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
//--------------------------------------------------------------------------------//
template <class T>
struct SegTree {
    int n;
    vector<T> data;
    // 単位元
    T id;
    // 二項演算 区間取得operate, 一点更新change
    function<T(T, T)> operate, change;

    SegTree(
        int _n, T _id,
        function<T(T, T)> _ch = [](T d1, T d2) { return d1 + d2; },
        function<T(T, T)> _op = [](T d1, T d2) { return min(d1, d2); }
    )
        : id(_id), change(_ch), operate(_op) {
        n = 1;
        while(n < _n) n *= 2;
        data = vector<T>(2 * n + 1, id);
    }

    // i(0-indexed)をxで更新
    void update(int i, T x) {
        // 内部は1-indexed
        i += n;
        data[i] = change(data[i], x);
        while(i > 1) {
            i /= 2;
            data[i] = operate(data[i * 2], data[i * 2 + 1]);
        }
    }

    // [l, r)の区間クエリ
    T query(int l, int r){
        int L = l + n, R = r + n;
        T ret = id;
        // 非再帰区間取得
        while(L < R){
            if(L & 1){
                ret = operate(ret, data[L]);
                L++;
            }
            if(R & 1){
                R--;
                ret = operate(ret, data[R]);
            }
            L /= 2, R /= 2;
        }
        return ret;
    }

    void build(){
        for (int i = n - 1; i > 0; i--) data[i] = operate(data[i * 2], data[i * 2 + 1]);
    }

    // 添字でアクセス
    T& operator[](int i) {
        return data[i + n];
    }
};
// SegTree<T> seg(N, id, change, operate) 要素数, 単位元, 更新関数, 取得関数
// デフォルト引数　change: add, operate: min
// query(l, r) 区間取得(半開区間), update(l, x) 一点更新

int main() {
    init();
    ll H, W, M;
    cin >> H >> W >> M;

    auto ch = [](ll d1, ll d2) { return d1 + d2; };
    auto op = [](ll d1, ll d2) { return max(d1, d2); };

    SegTree<ll> R(H, 0, ch, op);

    vvc<ll> A(W);
    vl cnt(H);
    rep(i, M) {
        ll h, w;
        cin >> h >> w;
        h--, w--;
        A[w].eb(h);
        cnt[h]++;
    }
    rep(i, H) R[i] = cnt[i];
    R.build();


    ll ans = 0;
    rep(w, W) {
        repa(h, A[w]) R.update(h, -1);

        ll tmp = A[w].size();
        chmax(ans, tmp + R.query(0, H));

        repa(h, A[w]) R.update(h, 1);
    }

    cout << ans << endl;
}

Measured memory_bytes: 30136