#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2,fma")
#include <bits/stdc++.h>
#define all(x) std::begin(x), std::end(x)
#define isz(x) (int)std::size(x)
const auto io_sync_off = [](){
    std::ios_base::sync_with_stdio(0); std::cin.tie(0);
    std::cout << std::fixed << std::setprecision(9);
    return 0;
}();
// Debug defines:
#define watch(x) std::cerr << std::setw(12) << #x << " = " << std::setw(12) << x
#define watchln(x) watch(x) << std::endl
#define watchsp(x) watch(x) << " "
#define cerr cerr && debug && std::cerr
// Defines:
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using vi = std::vector<int>;
using vl = std::vector<ll>;
using vs = std::vector<std::string>;
using vvi = std::vector<vi>;
using vvl = std::vector<vl>;
using vb = std::vector<bool>;
using vvb = std::vector<vb>;
using pii = std::pair<int,int>;
using pil = std::pair<int,ll>;
using pli = std::pair<ll,int>;
using pll = std::pair<ll,ll>;
using vpii = std::vector<pii>;
using vvpii = std::vector<vpii>;
// Comparators:
template<typename A, typename B> bool operator >(const A& a, const B& b) { return b < a; }
template<typename A, typename B> bool operator<=(const A& a, const B& b) { return !(a > b); }
template<typename A, typename B> bool operator>=(const A& a, const B& b) { return !(a < b); }
template<typename A, typename B> bool operator!=(const A& a, const B& b) { return a < b || b < a; }
template<typename A, typename B> bool operator==(const A& a, const B& b) { return !(a != b); }
namespace std {
#if __cplusplus < 201703L
    // Containers:
    template <typename T> constexpr auto size(const T& t) -> decltype(t.size()) { return t.size(); }
#endif
    // 2D arrays:
    template<typename T, int N, int M> auto size(const T (&)[N][M]) { return N * M; }
    template<typename T, int N, int M> auto begin(T (&a)[N][M]) { return &a[0][0]; }
    template<typename T, int N, int M> auto end(T (&a)[N][M]) { return &a[0][0] + N * M; }
    // 3D arrays:
    template<typename T, int N, int M, int K> auto size(const T (&)[N][M][K]) { return N * M * K; }
    template<typename T, int N, int M, int K> auto begin(T (&a)[N][M][K]) { return &a[0][0][0]; }
    template<typename T, int N, int M, int K> auto end(T (&a)[N][M][K]) { return &a[0][0][0] + N * M * K; }
    // Algorithms:
    template<typename C> void reuniq(C& c) { c.erase(unique(all(c)), end(c)); }
    template<typename C, typename X> int lowpos(const C& c, X x) {
        return int(lower_bound(all(c), x) - begin(c));
    }
    template<typename C, typename X> int uppos(const C& c, X x) {
        return int(upper_bound(all(c), x) - begin(c));
    }
    template<typename X, typename Y> X& remin(X& x, const Y& y) { return x = (y < x) ? y : x; }
    template<typename X, typename Y> X& remax(X& x, const Y& y) { return x = (x < y) ? y : x; }
}
// Rand:
namespace Rand {
    const auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
    std::mt19937 gen(seed ^ ull(std::make_unique<char>().get()));
}
// Input:
template<typename T> std::istream& operator>>(std::istream& is, std::vector<T>& vec) {
    for (auto &it : vec) is >> it;
    return is;
}
// Output:
template<typename A, typename B> std::ostream& operator<<(std::ostream& os, const std::pair<A,B>& pt) {
    return os << "{" << pt.first << ", " << pt.second << "}";
}
template<typename Iterator>
std::ostream& print_range(std::ostream& os, Iterator begin, Iterator end) {
    os << "{";
    for (auto it = begin; it != end; it++) {
        if (it != begin) { os << ", "; }
        os << *it;
    }
    return os << "}";
}
template<typename T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
    return print_range(os, vec.begin(), vec.end());
}
template<typename T> std::ostream& operator<<(std::ostream& os, const std::set<T>& set) {
    return print_range(os, set.begin(), set.end());
}
// Operators << and >> for containers:
template<typename T> std::queue<T>& operator<<(std::queue<T>& q, const T& x) { return q.push(x), q; }
template<typename T> std::queue<T>& operator--(std::queue<T>& q, int) { return q.pop(), q; }
template<typename T> std::queue<T>& operator>>(std::queue<T>& q, T& x) {  return x = q.front(), q--; }

template<typename T> std::vector<T>& operator<<(std::vector<T>& v, const T& x) { return v.push_back(x), v; }
template<typename T> std::vector<T>& operator--(std::vector<T>& v, int) { return v.pop_back(), v; }
template<typename T> std::vector<T>& operator>>(std::vector<T>& v, T& x) { return x = v.back(), v--; }

template<typename T> std::vector<T>& operator<<(std::vector<T>& a, const std::vector<T>& b) {
    return a.insert(a.end(), all(b)), a;
}

template<typename T>
std::list<T>& operator<<(std::list<T>& a, const std::list<T>& b) {
    return a.insert(a.end(), b.begin(), b.end()), a;
}

template<typename T>
std::list<T>& operator>>(const std::list<T>& a, std::list<T>& b) {
    return b.insert(b.begin(), a.begin(), a.end()), b;
}

// Variables:
const int debug = 0;
// -----------------------------------------------------------------------------
int main() {
    int nRows,nCols,n;
    while (std::cin >> nRows >> nCols >> n) {
        std::map<int,vi> targets;
        vi count(1+nCols+1);
        std::multiset<int, std::greater<int>> set = {0};
        for (int c = 1; c <= nCols; c++) set.insert(0);
        auto add = [&](int c) {
            set.erase(set.find(count[c]));
            count[c]++;
            set.insert(count[c]);
        };
        auto rem = [&](int c) {
            set.erase(set.find(count[c]));
            count[c]--;
            set.insert(count[c]);
        };
        for (int i = 0; i < n; i++) {
            int r,c; std::cin >> r >> c;
            targets[r].push_back(c);
            add(c);
        }
        int answ(0);
        for (auto& [r,list] : targets) {
            for (auto &c : list) {
                std::remax(answ, isz(list) - 1 + count[c]);
                rem(c);
            }
            std::remax(answ,isz(list) + *set.begin());
            for (auto &c : list) {
                add(c);
            }
        }
        std::cout << answ << std::endl;
    }
    
    return 0;
}

Measured memory_bytes: 51240