CodeEff/ECCO huggingface dataset:
# Original solution
from sys import stdin
input = stdin.readline
from collections import defaultdict, deque
h, w, m = list(map(int,input().split()))
row = defaultdict(int)
col = defaultdict(int)
grid = defaultdict(int)
for _ in range(m):
    x,y = list(map(int,input().split()))
    row[x]+=1
    col[y]+=1
    grid[(x,y)]=1


row = sorted(list(row.items()), key = lambda x: x[1], reverse = True)
col = sorted(list(col.items()), key = lambda x: x[1], reverse = True)
i,j = 0,0
ans = row[0][1]+col[0][1] + (-1 if grid[(row[0][0], col[0][0])] else 0)
dq = deque([(i,j)])
while dq:
    i,j = dq.popleft()
    temp = row[i][1]+col[j][1] + (-1 if grid[(row[i][0], col[j][0])] else 0)
    if ans<temp:
        ans = temp
        break
    
    if i+1<len(row):dq.append((i+1,j))
    if j+1<len(col):dq.append((i,j+1))

    
print(ans)

# Optimized solution
from sys import stdin
input = stdin.readline
from collections import defaultdict, deque
h, w, m = list(map(int,input().split()))
row = defaultdict(int)
col = defaultdict(int)
grid = defaultdict(int)
for _ in range(m):
    x,y = list(map(int,input().split()))
    row[x]+=1
    col[y]+=1
    grid[(x,y)]=1


row = sorted(list(row.items()), key = lambda x: x[1], reverse = True)
col = sorted(list(col.items()), key = lambda x: x[1], reverse = True)


#print(row)
#print(col)

t = len(row)
for idx, ele in enumerate(row):
    i,j = ele
    if j!=row[0][1]:
        t = idx
        break
row = row[:t]
t = len(col)
for idx, ele in enumerate(col):
    i,j = ele
    if j!=col[0][1]:
        t = idx
        break
col = col[:t]

#print(row)
#print(col)
#print(grid)

ans = row[0][1]+col[0][1] + (-1 if grid[(row[0][0], col[0][0])] else 0)

i,j = 0,0
for r,cr in row:
    for c,cc in col:
        if not grid[(r,c)]:
            ans = cr+cc
            break
print(ans)


# dq = deque([(i,j)])
# while dq:
#     i,j = dq.popleft()
#     temp = row[i][1]+col[j][1] + (-1 if grid[(row[i][0], col[j][0])] else 0)
#     if ans<temp:
#         ans = temp
#         break
    
#     if i+1<len(row):dq.append((i+1,j))
#     if j+1<len(col):dq.append((i,j+1))

    
# print(ans)
# Original solution
#from statistics import median
#import collections
#aa = collections.Counter(a) # list to list || .most_common(2)で最大の2個とりだせるお a[0][0]
from math import gcd
from itertools import combinations,permutations,accumulate, product # (string,3) 3回
#from collections import deque
from collections import deque,defaultdict,Counter
import decimal
import re
import math
import bisect
import heapq
#
#
#
# pythonで無理なときは、pypyでやると正解するかも！！
#
#
# my_round_int = lambda x:np.round((x*2 + 1)//2)
# 四捨五入g
#
# インデックス系
# int min_y = max(0, i - 2), max_y = min(h - 1, i + 2);
# int min_x = max(0, j - 2), max_x = min(w - 1, j + 2);
#
#
import sys
sys.setrecursionlimit(10000000)
mod = 10**9 + 7
#mod = 9982443453
#mod = 998244353
INF = float('inf')
from sys import stdin
readline = stdin.readline
def readInts():
  return list(map(int,readline().split()))
def readTuples():
    return tuple(map(int,readline().split()))
def I():
    return int(readline())
H,W,M = readInts()

dic1 = defaultdict(int)
dic2 = defaultdict(int)
s = set()
for i in range(M):
    h,w = [int(x)-1 for x in input().split()]
    dic1[h] += 1
    dic2[w] += 1
    s.add((h,w))
# print(dic)
ans = 0


# 辞書の値が最大・最小となるキーを取得
max1 = max(dic1.values())
max2 = max(dic2.values())
for k1,v1 in list(dic1.items()):
    if v1 < max1:
        continue
    for k2,v2 in list(dic2.items()):
        if v2 < max2:
            continue
        if (k1,k2) in s:
            ans = max(ans,dic1[k1] + dic2[k2] - 1)
        else:
            ans = max(ans,dic1[k1] + dic2[k2])
print(ans)


# Optimized solution
#from statistics import median
#import collections
#aa = collections.Counter(a) # list to list || .most_common(2)で最大の2個とりだせるお a[0][0]
from math import gcd
from itertools import combinations,permutations,accumulate, product # (string,3) 3回
#from collections import deque
from collections import deque,defaultdict,Counter
import decimal
import re
import math
import bisect
import heapq
#
#
#
# pythonで無理なときは、pypyでやると正解するかも！！
#
#
# my_round_int = lambda x:np.round((x*2 + 1)//2)
# 四捨五入g
#
# インデックス系
# int min_y = max(0, i - 2), max_y = min(h - 1, i + 2);
# int min_x = max(0, j - 2), max_x = min(w - 1, j + 2);
#
#
import sys
sys.setrecursionlimit(10000000)
mod = 10**9 + 7
#mod = 9982443453
#mod = 998244353
INF = float('inf')
from sys import stdin
readline = stdin.readline
def readInts():
  return list(map(int,readline().split()))
def readTuples():
    return tuple(map(int,readline().split()))
def I():
    return int(readline())
H,W,M = readInts()

dic1 = Counter()
dic2 = Counter()
s = set()
for i in range(M):
    h,w = [int(x)-1 for x in input().split()]
    dic1[h] += 1
    dic2[w] += 1
    s.add((h,w))
# print(dic)
ans = 0

# 重なっているもので最大値がある時もあれば
# 行、列の交差点でボムなしが一番大きいものがある
for h,w in s:
    ans = max(ans, dic1[h] + dic2[w] - 1)

dic1 = dic1.most_common()
dic2 = dic2.most_common()
max1 = dic1[0][1]
max2 = dic2[0][1]

for k1,v1 in dic1:
    if v1 < max1:
        break # continueする必要がない most_commonで大きい方から集めてるので
    for k2,v2 in dic2:
        if v2 < max2:
            break # 同じく
        if (k1,k2) in s: # 一度計算したもの
            continue
        # 両方とも最大であればok
        ans = max(ans, v1 + v2)
        break
print(ans)
# Original solution
#!/usr/bin/env python3

import collections
import sys
input=sys.stdin.readline

h,w,m=list(map(int,input().split()))
items=[set() for _ in range(h+1)]
count_h=[0]*(h+1)
count_w=[0]*(w+1)
for _ in range(m):
    y,x=list(map(int,input().split()))
    items[y].add(x)
    count_h[y]+=1
    count_w[x]+=1
count_num=collections.defaultdict(int)
for x in range(1,w+1):
    count_num[count_w[x]]+=1
count_cand=list(count_num.keys())
count_cand=sorted(count_cand,reverse=True)
ans=0
for y in range(1,h+1):
    value_y=count_h[y]
    count_tmp=collections.defaultdict(int)
    for x in items[y]:
        value_x=count_w[x]
        count_tmp[value_x]+=1
        ans=max(ans,value_y+value_x-1)
    for x in count_cand:
        if count_num[x]>count_tmp[x]:
            ans=max(ans,value_y+x)
            break
print(ans)

# Optimized solution
#!/usr/bin/env python3

import collections
import sys
input=sys.stdin.readline

h,w,m=list(map(int,input().split()))
items=set()
count_h=[0]*(h+1)
count_w=[0]*(w+1)
for _ in range(m):
    y,x=list(map(int,input().split()))
    items.add((y,x))
    count_h[y]+=1
    count_w[x]+=1
max_h=max(count_h)
max_w=max(count_w)
cand_h=[]
cand_w=[]
for y in range(1,h+1):
  if count_h[y]==max_h:
    cand_h.append(y)
for x in range(1,w+1):
  if count_w[x]==max_w:
    cand_w.append(x)
ans=max_h+max_w
for y in cand_h:
  for x in cand_w:
    if (y,x) not in items:
      print(ans)
      exit()
else:
  print((ans-1))
# Original solution
#import random

def putmx(lis,mx):
  ret=[]
  for (i,j) in zip(list(range(len(lis))),lis):
    if j==mx:
      ret.append(i)
  return ret
  

h,w,m=list(map(int,input().split()))
hb=[0]*h
wb=[0]*w
bmb=[]
for i in range(h):
  bmb.append([])
for i in range(m):
  hh,ww=list(map(int,input().split()))
  hh-=1
  ww-=1
  bmb[hh].append(ww)
  hb[hh]+=1
  wb[ww]+=1
mhb=max(hb)
mwb=max(wb)
hmx=putmx(hb,mhb)
wmx=putmx(wb,mwb)

#print(hb,wb,hmx,wmx)
fl=False
for i in hmx:
  for j in wmx:
    if not j in bmb[i]:
      print((mhb+mwb))
      fl=True
      break
  if fl:
    break
else:
  print((mhb+mwb-1))



# Optimized solution
#import random

def putmx(lis,mx):
  ret=[]
  for (i,j) in zip(list(range(len(lis))),lis):
    if j==mx:
      ret.append(i)
  return ret
  

h,w,m=list(map(int,input().split()))
hb=[0]*h
wb=[0]*w
bmb=[]
for i in range(h):
  bmb.append({-1})
for i in range(m):
  hh,ww=list(map(int,input().split()))
  hh-=1
  ww-=1
  bmb[hh].add(ww)
  hb[hh]+=1
  wb[ww]+=1
mhb=max(hb)
mwb=max(wb)
hmx=putmx(hb,mhb)
wmx=set(putmx(wb,mwb))

#print(hb,wb,hmx,wmx)
fl=False
for i in hmx:
  if wmx|bmb[i]!=bmb[i]:
    print((mhb+mwb))
    break
else:
  print((mhb+mwb-1))

#print(hmx,wmx,bmb)
# Original solution
#!/usr/bin/env python3
def main():
    import sys
    input = sys.stdin.readline
    h, w, m = list(map(int, input().split()))
    cnt_h = [0] * h
    cnt_w = [0] * w
    bomb = [[False] * w for _ in range(h)]
    for _ in range(m):
        y, x = [int(x) - 1 for x in input().split()]
        cnt_h[y] += 1
        cnt_w[x] += 1
        bomb[y][x] = 1
        
    kouho_h = []
    kouho_w = []
    max_h = max(cnt_h)
    max_w = max(cnt_w)
    for i in range(h):
        if cnt_h[i] == max_h:
            kouho_h.append(i)
    for i in range(w):
        if cnt_w[i] == max_w:
            kouho_w.append(i)
    
    for i in kouho_h:
        for j in kouho_w:
            if bomb[i][j] == False:
                print((max_h + max_w))
                exit()
    print((max_h + max_w - 1))



if __name__ == '__main__':
    main()

# Optimized solution
#!/usr/bin/env python3
def main():
    import sys
    input = sys.stdin.readline
    h, w, m = list(map(int, input().split()))
    cnt_h = [0] * h
    cnt_w = [0] * w
    bomb = set()
    for _ in range(m):
        y, x = [int(x) - 1 for x in input().split()]
        cnt_h[y] += 1
        cnt_w[x] += 1
        bomb.add((y, x))
        
    kouho_h = []
    kouho_w = []
    max_h = max(cnt_h)
    max_w = max(cnt_w)
    for i in range(h):
        if cnt_h[i] == max_h:
            kouho_h.append(i)
    for i in range(w):
        if cnt_w[i] == max_w:
            kouho_w.append(i)
    
    for i in kouho_h:
        for j in kouho_w:
            if (i, j) not in bomb:
                print((max_h + max_w))
                exit()
    print((max_h + max_w - 1))



if __name__ == '__main__':
    main()
# Original solution
import sys
input = sys.stdin.buffer.readline

def main():

    H, W, M = list(map(int, input().split()))
    #HW = [0]*m

    HC = [0]*H
    WC = [0]*W

    A = [0]*M

    for i in range(M):
        h, w = list(map(int, input().split()))
        h, w = h-1, w-1
        #HW[i] = (h, w)
        HC[h] += 1
        WC[w] += 1
        A[i] = (h, w)

    from collections import Counter
    hct = Counter(HC)
    wct = Counter(WC)
    hct = list(hct.items())
    wct = list(wct.items())
    hct.sort(reverse=True)
    wct.sort(reverse=True)
    #print(hct)
    #print(wct)
    temph = hct[0][0]
    tempw= wct[0][0]
    tempa = temph+tempw
    cnthw = hct[0][1]*wct[0][1]
    cnt = 0
    for h, w in A:
        if HC[h]+WC[w] ==tempa:
            cnt += 1
    #print(cnt, cnthw)
    if cnt < cnthw:
        print(tempa)
    else:
        print((tempa-1))

if __name__ == '__main__':
    main()


# Optimized solution
import sys
import io, os
#input = sys.stdin.buffer.readline
input = io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

h, w, m = list(map(int, input().split()))
R = [0]*h
C = [0]*w
YX = []
for i in range(m):
    y, x = list(map(int, input().split()))
    y, x = y-1, x-1
    R[y] +=1
    C[x] +=1
    YX.append((y, x))

max_r = max(R)
max_c = max(C)
cr = 0
cc = 0
for i in range(h):
    if R[i] == max_r:
        cr += 1
for i in range(w):
    if C[i] == max_c:
        cc +=1
c = 0
for y, x in YX:
    if R[y] == max_r and C[x] == max_c:
        c += 1
if c < cr*cc:
    print((max_r+max_c))
else:
    print((max_r+max_c-1))
# Original solution
import sys

H, W, M = list(map(int,input().split()))
R = [0] * H
C = [0] * W

S = set()

for _ in range(M):
    h, w = list(map(int,input().split()))
    S.add((h-1, w-1))
    R[h-1] += 1
    C[w-1] += 1

r = max(R)
c = max(C)

HL = [i for i in range(H) if R[i] == r]
WL = [i for i in range(W) if C[i] == c]

for h in HL:
    for w in WL:
        if not (h, w) in S:
            print((r + c))
            sys.exit()

print((r + c - 1))

# Optimized solution
H, W, M = list(map(int,input().split()))
R = [0] * H
C = [0] * W

L = []

for _ in range(M):
    h, w = list(map(int,input().split()))
    R[h-1] += 1
    C[w-1] += 1
    L.append([h-1, w-1])

r = max(R)
c = max(C)

print((r + c - (R.count(r) * C.count(c) == sum(R[h] + C[w] == r + c for h, w in L))))
# Original solution
import sys
sys.setrecursionlimit(10**7)

readline = sys.stdin.buffer.readline
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print(('\n'.join(map(str,x))))
def printline(x):print((' '.join(map(str,x))))

import bisect
from operator import itemgetter

h,w,m = readints()

r = [0]*h
c = [0]*w

p = [readints() for i in range(m)]
p.sort(key=itemgetter(1))

d = [[] for i in range(h)]
for i in range(m):
    a,b = (x-1 for x in p[i])
    r[a] += 1
    c[b] += 1
    d[a].append(b)

mr = max(r)
mc = max(c)
R = [i for i,x in enumerate(r) if x==mr]
C = [i for i,x in enumerate(c) if x==mc]

flag = 1
if len(R)*len(C)>m:
    flag = 0
else:
    for x in R:
        for y in C:
            z = bisect.bisect_left(d[x],y)
            if z>=len(d[x]):
                flag = 0
                break
            else:
                if y != d[x][z]:
                    flag = 0
                    break

print((max(r)+max(c)-flag))






# Optimized solution
import sys
sys.setrecursionlimit(10**7)

readline = sys.stdin.buffer.readline
def readstr():return readline().rstrip().decode()
def readstrs():return list(readline().decode().split())
def readint():return int(readline())
def readints():return list(map(int,readline().split()))
def printrows(x):print(('\n'.join(map(str,x))))
def printline(x):print((' '.join(map(str,x))))

h,w,m = readints()

r = [0]*h
c = [0]*w

d = [set() for i in range(h)]
for i in range(m):
    a,b = (x-1 for x in readints())
    r[a] += 1
    c[b] += 1
    d[a].add(b)

mr = max(r)
mc = max(c)
R = [i for i,x in enumerate(r) if x==mr]
C = [i for i,x in enumerate(c) if x==mc]

flag = 1
if len(R)*len(C)>m:
    flag = 0
else:
    for x in R:
        for y in C:
            if y not in d[x]:
                flag = 0
                break

print((max(r)+max(c)-flag))
# Original solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

h, w, m = LI()
bomb = defaultdict(lambda : 0)
cnt_h = [0] * h
cnt_w = [0] * w
for _ in range(m):
    H, W = LI()
    bomb[(H-1, W-1)] = 1
    cnt_h[H-1] += 1
    cnt_w[W-1] += 1

m_h = max(cnt_h)
m_w = max(cnt_w)
H_l = []
W_l = []
for i in range(h):
    if cnt_h[i] == m_h:
        H_l.append(i)

for i in range(w):
    if cnt_w[i] == m_w:
        W_l.append(i)

ans = m_h + m_w

flag = False
for i in H_l:
    for j in W_l:
        if not bomb[(i, j)]:
            flag = True
if flag:
    print(ans)
else:
    print((ans-1))

# Optimized solution
#!/usr/bin/env python3

import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop,heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7
inf = float('inf')
def I(): return int(sys.stdin.readline())
def LI(): return list(map(int,sys.stdin.readline().split()))

h, w, m = LI()
bomb = defaultdict(lambda : 0)
cnt_h = [0] * h
cnt_w = [0] * w
for _ in range(m):
    H, W = LI()
    bomb[(H-1, W-1)] = 1
    cnt_h[H-1] += 1
    cnt_w[W-1] += 1

m_h = max(cnt_h)
m_w = max(cnt_w)
H_l = []
W_l = []
for i in range(h):
    if cnt_h[i] == m_h:
        H_l.append(i)

for i in range(w):
    if cnt_w[i] == m_w:
        W_l.append(i)

ans = m_h + m_w

for i in H_l:
    for j in W_l:
        if not bomb[(i, j)]:
            print(ans)
            quit()
print((ans-1))
# Original solution
import sys
from collections import Counter
H,W,m = list(map(int,input().split()))
h_ls = [0] * H
w_ls = [0] * W
bombers = [[0,0] for _ in range(m)]
for i in range(m):
    h,w = list(map(int,input().split()))
    h_ls[h-1] += 1
    w_ls[w-1] += 1
    bombers[i] = [h-1,w-1]

h_max = max(h_ls)
h_counter = Counter(h_ls)
# Couter使ってみる
h_max_args = [0]*h_counter[h_max]
next_ind = 0
for i in range(H):
    if h_ls[i] == h_max:
        h_max_args[next_ind] = i
        next_ind += 1

w_max = max(w_ls)
w_counter = Counter(w_ls)
w_max_args = [0]*w_counter[w_max]
next_ind = 0
for i in range(W):
    if w_ls[i] == w_max:
        w_max_args[next_ind] = i
        next_ind += 1

for h in h_max_args:
    for w in w_max_args:
        if not [h,w] in bombers:
            print((w_max+h_max))
            sys.exit()

print((w_max+h_max-1))

# Optimized solution
import sys
from collections import Counter
H,W,m = list(map(int,input().split()))
h_ls = [0] * H
w_ls = [0] * W
bombers = [(0,0) for _ in range(m)]
for i in range(m):
    h,w = list(map(int,input().split()))
    h_ls[h-1] += 1
    w_ls[w-1] += 1
    bombers[i] = (h-1,w-1)

h_max = max(h_ls)
h_counter = Counter(h_ls)
# Couter使ってみる
h_max_args = [0]*h_counter[h_max]
next_ind = 0
for i in range(H):
    if h_ls[i] == h_max:
        h_max_args[next_ind] = i
        next_ind += 1

w_max = max(w_ls)
w_counter = Counter(w_ls)
w_max_args = [0]*w_counter[w_max]
next_ind = 0
for i in range(W):
    if w_ls[i] == w_max:
        w_max_args[next_ind] = i
        next_ind += 1

bombers = set(bombers)
for h in h_max_args:
    for w in w_max_args:
        if not (h,w) in bombers:
            print((w_max+h_max))
            sys.exit()

print((w_max+h_max-1))
# Original solution
import sys
input = sys.stdin.readline

def segfunc(x,y):
  return max(x,y)

class SegmentTree(object):
    def __init__(self, A, dot, unit):
        n = 1 << (len(A) - 1).bit_length()
        tree = [unit] * (2 * n)
        for i, v in enumerate(A):
            tree[i + n] = v
        for i in range(n - 1, 0, -1):
            tree[i] = dot(tree[i << 1], tree[i << 1 | 1])
        self._n = n
        self._tree = tree
        self._dot = dot
        self._unit = unit

    def __getitem__(self, i):
        return self._tree[i + self._n]

    def update(self, i, v):
        i += self._n
        self._tree[i] = v
        while i != 1:
            i >>= 1
            self._tree[i] = self._dot(self._tree[i << 1], self._tree[i << 1 | 1])

    def add(self, i, v):
        self.update(i, self[i] + v)

    def sum(self, l, r): #これで[l,r)から取り出す。
        l += self._n
        r += self._n
        l_val = r_val = self._unit
        while l < r:
            if l & 1:
                l_val = self._dot(l_val, self._tree[l])
                l += 1
            if r & 1:
                r -= 1
                r_val = self._dot(self._tree[r], r_val)
            l >>= 1
            r >>= 1
        return self._dot(l_val, r_val)
INF = float("inf")
H,W,M = list(map(int,input().split()))
A = [0 for _ in range(H)]
B = [0 for _ in range(W)]
Treeh = SegmentTree(A,segfunc,-INF)
Treew = SegmentTree(B,segfunc,-INF)
G = [[False]*W for _ in range(H)]
for i in range(M):
  h,w = list(map(int,input().split()))
  h-=1;w-=1
  G[h][w] = True
  Treeh.add(h,1)
  Treew.add(w,1)
X = Treeh.sum(0,H)
Y = Treew.sum(0,W)
MaxX_L = []
for i in range(H):
  #print(Treeh.__getitem__(i))
  if Treeh.__getitem__(i) == X:
    MaxX_L.append(i)
MaxY_L = []
for i in range(W):
  #print(Treeh.__getitem__(i))
  if Treew.__getitem__(i) == Y:
    MaxY_L.append(i)
ans = X+Y
for x in MaxX_L:
  for y in MaxY_L:
    if not G[x][y]:
      print(ans)
      exit()
ans -= 1

print(ans)

# Optimized solution
H,W,M = list(map(int,input().split()))
Bomb = []
H_num = [0 for _ in range(H)]
W_num = [0 for _ in range(W)]
for i in range(M):
  a,b = list(map(int,input().split()))
  a-=1;b-=1
  Bomb.append([a,b])
  H_num[a] += 1
  W_num[b] += 1

HMAX = max(H_num);WMAX = max(W_num)
ans = HMAX+WMAX
HMAX_list = set([]); WMAX_list = set([])
for i in range(H):
  if H_num[i] == HMAX:
    HMAX_list.add(i)
for i in range(W):
  if W_num[i] == WMAX:
    WMAX_list.add(i)
kosu = len(HMAX_list)*len(WMAX_list)
cnt = 0
for z in Bomb:
  x = z[0];y = z[1]
  if x in HMAX_list and y in WMAX_list:
    cnt += 1
#print(kosu,cnt)
if cnt < kosu:
  print(ans)
else:
  print((ans-1))
# Original solution
from collections import defaultdict

h, w, m = list(map(int, input().split()))

cnt_h = [0] * h
cnt_w = [0] * w
dic = defaultdict(int)

for _ in range(m):
    h_m, w_m = list(map(int, input().split()))
    cnt_h[h_m - 1] += 1
    cnt_w[w_m - 1] += 1
    dic[h_m - 1, w_m - 1] += 1

max_h = max(cnt_h)
max_w = max(cnt_w)

mh = []
mw = []

for i in range(h):
    if max_h == cnt_h[i]:
        mh.append(i)

for i in range(w):
    if max_w == cnt_w[i]:
        mw.append(i)

flag = False
for i in mh:
    for j in mw:
        if dic[i, j] == 0:
            flag = True

if flag:
    print((max_h + max_w))
else:
    print((max_h + max_w - 1))

# Optimized solution
from collections import defaultdict

h, w, m = list(map(int, input().split()))

cnt_h = [0] * h
cnt_w = [0] * w
dic = defaultdict(int)

for _ in range(m):
    h_m, w_m = list(map(int, input().split()))
    cnt_h[h_m - 1] += 1
    cnt_w[w_m - 1] += 1
    dic[(h_m - 1, w_m - 1)] += 1

max_h = max(cnt_h)
max_w = max(cnt_w)

mh = []
mw = []

for i in range(h):
    if max_h == cnt_h[i]:
        mh.append(i)

for i in range(w):
    if max_w == cnt_w[i]:
        mw.append(i)

for i in mh:
    for j in mw:
        if dic[(i, j)] == 0:
            print((max_h + max_w))
            quit()

print((max_h + max_w - 1))
# Original solution
import sys
import random
H,W,M=list(map(int,input().split()))

hlist=[0]*H
wlist=[0]*W
hwset=set()
for _ in range(M):
  h,w=list(map(int,input().split()))
  hlist[h-1]+=1
  wlist[w-1]+=1
  hwset.add((h-1,w-1))
  
hmax=max(hlist)
wmax=max(wlist)

hlist2=[]
for i in range(H):
  if hlist[i]==hmax:
    hlist2.append(i)
hlist2.sort(reverse=True)
random.shuffle(hlist2)

wlist2=[]
for i in range(W):
  if wlist[i]==wmax:
    wlist2.append(i)
wlist2.sort(reverse=True)
random.shuffle(wlist2)

#print(hlist2,wlist2)
H2=len(hlist2)
W2=len(wlist2)

if H2*W2>=10**7:
  norm=(H2*W2)//(10**7)
  H2=int(H2/(norm**0.5))
  W2=int(W2/(norm**0.5))

for i in range(H2):
  ii=hlist2[i]
  for j in range(W2):
    jj=wlist2[j]
    if not (ii,jj) in hwset:
      print((hmax+wmax))
      sys.exit(0)
else:
  print((hmax+wmax-1))

# Optimized solution
import sys
H,W,M=list(map(int,input().split()))

hlist=[0]*H
wlist=[0]*W
hwset=set()
for _ in range(M):
  h,w=list(map(int,input().split()))
  hlist[h-1]+=1
  wlist[w-1]+=1
  hwset.add((h-1,w-1))
  
hmax=max(hlist)
hlist2=[]
for i in range(H):
  if hlist[i]==hmax:
    hlist2.append(i)

wmax=max(wlist)
wlist2=[]
for i in range(W):
  if wlist[i]==wmax:
    wlist2.append(i)
#print(hlist2,wlist2)

H2=len(hlist2)
W2=len(wlist2)

if H2*W2>M:
  print((hmax+wmax))
else:
  for i in range(H2):
    ii=hlist2[i]
    for j in range(W2):
      jj=wlist2[j]
      if not (ii,jj) in hwset:
        print((hmax+wmax))
        sys.exit(0)
  else:
    print((hmax+wmax-1))