let startTime = Date()

import Foundation

let MOD = 10 ** 9 + 7
let alphabets = "abcdefghijklmnopqrstuvwxyz"
let ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
let Yes = "Yes"
let No = "No"
prefix operator *
infix operator **: PowerPrecedence
precedencegroup PowerPrecedence {
    higherThan: MultiplicationPrecedence
    lowerThan: BitwiseShiftPrecedence
    associativity: right
}
prefix func * <T> (a: [T]) -> (T, T)             { return (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T)          { return (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T)       { return (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T)    { return (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { return (a[0], a[1], a[2], a[3], a[4], a[5]) }
func **(lhs: Int, rhs: Int) -> Int {
    return Int(pow(Double(lhs), Double(rhs)))
}
func **(lhs: Int, rhs: Double) -> Double {
    return pow(Double(lhs), rhs)
}
struct Stack<Element>: Collection {
    var items = [Element]()
    var startIndex: Int {
        return items.startIndex
    }
    var endIndex: Int {
        return items.endIndex
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
    func index(after index: Int) -> Int {
        return items.index(after: index)
    }
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeLast()
    }
}
struct Queue<Element>: Collection {
    var items = [Element]()
    var startIndex: Int {
        return items.startIndex
    }
    var endIndex: Int {
        return items.endIndex
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
    func index(after index: Int) -> Int {
        return items.index(after: index)
    }
    mutating func push(_ item: Element) {
        items.append(item)
    }
    mutating func pop() -> Element {
        return items.removeFirst()
    }
}
struct Heap<Element: Comparable>: Collection {
    var items = [Element]()
    var startIndex: Int {
        return items.startIndex
    }
    var endIndex: Int {
        return items.endIndex
    }
    subscript(i: Int) -> Element {
        return items[i]
    }
    func index(after index: Int) -> Int {
        return items.index(after: index)
    }
    mutating func push(_ item: Element) {
        var i = items.count
        while i > 0 {
            let p = (i - 1) / 2
            if items[p] <= item {
                break
            }
            if i == items.count {
                items.append(items[p])
            } else {
                items[i] = items[p]
            }
            i = p
        }
        if i == items.count {
            items.append(item)
        } else {
            items[i] = item
        }
    }
    mutating func pop() -> Element {
        let ret = items[0]
        let x = items[items.endIndex]
        var i: Int = 0
        while i * 2 + 1 < items.endIndex {
            var a = i * 2 + 1
            let b = i * 2 + 2
            if b < items.endIndex && items[b] < items[a] {
                a = b
            }
            if items[a] >= x {
                break
            }
            items[i] = items[a]
            i = a
        }
        items[i] = x
        items.removeLast()
        return ret
    }
}
extension Collection {
    func count(where predicate: (Element) -> Bool) -> Int {
        return self.reduce(0){$0+(predicate($1) ? 1 : 0)}
    }
}
extension Collection where Element: Equatable {
    func count(of value: Element) -> Int {
        return self.reduce(0){$0+($1==value ? 1 : 0)}
    }
}
extension Array {
    func indices(where predicate: (Element) -> Bool) -> [Int] {
        return (0..<self.count).filter{predicate(self[$0])}
    }
}
extension Array where Element: Equatable {
    func indices(of value: Element) -> [Int] {
        return (0..<self.count).filter{self[$0]==value}
    }
}
extension Array where Element: Hashable {
    func tally() -> Dictionary<Element, Int> {
        var dic = [Element: Int]()
        self.forEach{dic[$0, default: 0] += 1}
        return dic
    }
}
extension Array where Element == Int {
    // condition が "<=" なら lower_bound, ">=" なら upper_bound
    func binarySearch(_ key: Int, _ condition: (Int, Int) -> Bool) -> Int {
        var ng = -1
        var ok = self.count
        if !condition(ng, ok) {
            swap(&ng, &ok)
        }
        while abs(ok - ng) > 1 {
            let mid = (ok + ng) / 2
            if condition(key, self[mid]) {
                ok = mid
            } else {
                ng = mid
            }
        }
        return ok
    }
}
extension String {
    func replaceCharacter(from: Character, to: Character) -> String {
        return String(self.map{$0==from ? to : $0})
    }
    func replaceSubstring(from: String, to: String) -> String {
        return self.replacingOccurrences(of: from, with: to)
    }
    subscript(range: Range<Int>) -> String {
//        let start = self.index(self.startIndex, offsetBy: range.startIndex)
//        let end = self.index(start, offsetBy: range.endIndex - range.startIndex)
//        return String(self[start..<end])
        return String(Array(self)[range])
    }
    subscript(i: Int) -> Character {
//        return Character(self[i..<i+1])
        return Array(self)[i]
    }
}
func readInt() -> Int? {
    return Int(readLine()!)
}
func readStringsSplit(by separator: Character = " ") -> [String] {
    return readLine()!.split(separator: separator).map{String($0)}
}
func readIntsSplit(by separator: Character = " ") -> [Int] {
    return readLine()!.split(separator: separator).map{Int($0)!}
}
func gcd(_ x: Int, _ y: Int) -> Int {
    return y>0 ? gcd(y, x%y) : x
}
func lcm(_ x: Int, _ y: Int) -> Int {
    return x * y / gcd(x, y)
}
func primeNumbers(until n: Int) -> [Int] {
    var flags = Array(repeating: true, count: n+1)
    for i in 2...Int(n**0.5+0.5) {
        if flags[i] {
            for j in stride(from: i**2, to: n+1, by: i) {
                flags[j] = false
            }
        }
    }
    return (2...n).filter{flags[$0]}
}
func divisors(of n: Int) -> [Int] {
    var ret = [Int]()
    for i in 1...Int(n**0.5+0.5) {
        if n.isMultiple(of: i) {
            ret.append(i)
            if n/i != i {
                ret.append(n/i)
            }
        }
    }
    return ret.sorted()
}
func primeFactors(of n: Int) -> [Int] {
    var n = n
    if n == 1 {
        return [0, 1]
    } else if n == 2 {
        return [0, 0, 1]
    }
    var ret = Array(repeating: 0, count: n+1)
    for i in 2...Int(n**0.5+0.5) {
        while n.isMultiple(of: i) {
        ret[i] += 1
        n /= i
      }
    }
    if n != 1 {
        ret[n] = 1
    }
    return ret
}
func manhattanDist(_ x1: Int, _ y1: Int, _ x2: Int, _ y2: Int) -> Int {
    return abs(x1 - x2) + abs(y1 - y2)
}
func euclideanDist(_ x1: Int, _ y1: Int, _ x2: Int, _ y2: Int) -> Double {
    return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
}
func elapsedTime() -> Double {
    return Date().timeIntervalSince(startTime)
}

/****************************** メインプログラム ******************************/

let (H, W, M) = *readIntsSplit()
var arr = [(Int, Int)]()
var dic = [String: Bool]()
var x = Array(repeating: 0, count: H)
var y = Array(repeating: 0, count: W)

for _ in 0..<M {
    let (h, w) = *readIntsSplit().map{$0-1}
    arr.append((h, w))
    dic["\(h),\(w)"] = true
    x[h] += 1
    y[w] += 1
}

let maxX = x.max()!
let maxXIndex = (0..<H).filter{x[$0]==maxX}

let maxY = y.max()!
let maxYIndex = (0..<W).filter{y[$0]==maxY}

for i in maxXIndex {
    for j in maxYIndex {
        if dic["\(i),\(j)"] == nil {
            print(maxX+maxY)
            exit(0)
        }
    }
}
print(maxX+maxY-1)


Measured memory_bytes: 40816