#include<bits/stdc++.h>
 
using namespace std;
 
#define LL long long int
#define FASTIO ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
const int N = 3e5 + 5;
const int oo = 1e9 + 5;
const LL ooll = (LL)1e18 + 5;
const int MOD = 1e9 + 7;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
#define rand(l, r) uniform_int_distribution<int>(l, r)(rng)

clock_t start = clock();

template<class SegNode> struct SegTree {
    std::vector<SegNode> Tree;
    std::vector<int> lc, rc;
    int sz, L, R, rt;
    std::function<SegNode(SegNode, SegNode)> Merge;
    int construct_node() {
        sz++;
        Tree.push_back(SegNode());
        lc.push_back(-1); rc.push_back(-1);
        return sz-1;
    }
    void Lazy_Propagate(int node, int st, int en) {}
    void Lazy_Update(int node, SegNode val) {}
    SegTree() {
        sz = 0;
        Tree.clear();
        lc.clear();
        rc.clear();
    }
    SegTree(int L, int R, std::function<SegNode(SegNode, SegNode)> Merge) : L(L), R(R), Merge(Merge) {
        sz = 0;
        rt = construct_node();
    }
    SegTree(int L, int R, std::function<SegNode(SegNode, SegNode)> Merge, std::function<SegNode(int)> Init) : L(L), R(R), Merge(Merge) {
        sz = 0;
        rt = build_tree(L, R, Init);
    }
    int build_tree(int st, int en, std::function<SegNode(int)> &Init) {
        if (st == en) {
            int go = construct_node();
            Tree[go] = Init(st);
            return go;
        } 
        int m = (st + en) >> 1;
        int go = construct_node();
        int left_child = build_tree(st, m, Init);
        int right_child = build_tree(m+1, en, Init);
        lc[go] = left_child;
        rc[go] = right_child;
        Tree[go] = Merge(Tree[lc[go]], Tree[rc[go]]);
        return go;
    }
    void Pushdown(int node, int st, int en) {
        if (st < en) {
            if (lc[node] == -1) {
                int go = construct_node();
                lc[node] = go;
            }
            if (rc[node] == -1) {
                int go = construct_node();
                rc[node] = go;
            }
        }
        Lazy_Propagate(node, st, en);
    }
    void Point_Update(int pos, SegNode val, int node, int st, int en) {
        Pushdown(node, st, en);
        if (pos > en || pos < st) return;
        if (st == en) {
            Tree[node] += val;
            return;
        }
        int m = (st + en) >> 1;
        if (pos <= m) Point_Update(pos, val, lc[node], st, m);
        else Point_Update(pos, val, rc[node], m+1, en);
        Tree[node] = Merge(Tree[lc[node]], Tree[rc[node]]);
    }
    void Point_Update(int pos, SegNode val) {
        Point_Update(pos, val, rt, L, R);
    }
    SegNode Range_Query(int l, int r, int node, int st, int en) {
        Pushdown(node, st, en);
        if (st > r || en < l) return SegNode();
        if (st >= l && en <= r) return Tree[node];
        int m = (st + en) >> 1;
        return Merge(Range_Query(l, r, lc[node], st, m), Range_Query(l, r, rc[node], m+1, en));
    }
    SegNode Range_Query(int l, int r) {
        return Range_Query(l, r, rt, L, R);
    }
    void Range_Update(int l, int r, SegNode &val, int node, int st, int en) {
        Pushdown(node, st, en);
        if (st > r || en < l) return;
        if (st >= l && en <= r) {
            Lazy_Update(node, st, en, val);
            Lazy_Propagate(node, st, en);
            return;
        }
        int m = (st + en) >> 1;
        Range_Update(l, r, val, lc[node], st, m);
        Range_Update(l, r, val, rc[node], m+1, en);
        Tree[node] = Merge(Tree[lc[node]], Tree[rc[node]]);
    }
    void Range_Update(int l, int r, SegNode val) {
        return Range_Update(l, r, val, rt, L, R);
    }
    int Binary_Search(int x, int node, int st, int en); //{
    //     Pushdown(node, st, en);
    //     if (st == en) return st;
    //     int m = (st + en) >> 1;
    //     if (true) {
    //         return Binary_Search(x , rc[node], m+1, en);
    //     }
    //     return Binary_Search(x , lc[node], st, m);
    // }
    int Binary_Search(int x) {
        return Binary_Search(x, rt, L, R);
    }
    void Display(int node, int st, int en); // {
    //     cout << node << ": " << st << ',' << en << " = ";
    //     cout << '\n';
    //     if (st == en) return;
    //     Display(lc[node], st, m);
    //     Display(rc[node], m+1, en);
    // }
    void Display() {
        Display(rt, L, R);
    }
};

void solve() {  
    int h, w, m;
    cin >> h >> w >> m;

    SegTree<int> stree(1, w, [](int a, int b) {return max(a, b);}, [](int x) {return 0;});
    map<int, vector<int>> xmap;
    for (int i=0;i<m;++i) {
        int x, y;
        cin >> x >> y;
        stree.Point_Update(y, 1);
        xmap[x].push_back(y);
    }
    int ans = 0;
    for (auto it : xmap) {
        int x = it.first;
        vector<int> vy = it.second;
        for (auto y : vy) {
            stree.Point_Update(y, -1);
        } 
        ans = max(ans, (int)vy.size() + stree.Range_Query(1, w));
        for (auto y : vy) {
            stree.Point_Update(y, 1);
        } 
    }
    cout << ans << '\n';
}

int main() {
    FASTIO;
    int T = 1;
    // cin >> T;
    while(T--) {
        solve();
    }
    // cerr << fixed << setprecision(10);
    // cerr << (clock() - start) / ((long double)CLOCKS_PER_SEC) << '\n';
    return 0;
} 

Measured memory_bytes: 43208