Problem:
 Score : 500 points    Problem Statement We have a two-dimensional grid with H \times W squares. There are M targets to destroy in this grid - the position of the i -th target is \left(h_i, w_i \right) .  Takahashi will choose one square in this grid, place a bomb there, and ignite it. The bomb will destroy all targets that are in the row or the column where the bomb is placed. It is possible to place the bomb at a square with a target.  Takahashi is trying to maximize the number of targets to destroy. Find the maximum number of targets that can be destroyed.      Constraints  All values in input are integers.  1 \leq H, W \leq 3 \times 10^5  1 \leq M \leq \min\left(H\times W, 3 \times 10^5\right)  1 \leq h_i \leq H  1 \leq w_i \leq W  \left(h_i, w_i\right) \neq \left(h_j, w_j\right) \left(i \neq j\right)         Input Input is given from Standard Input in the following format:  H  W  M  h_1  w_1  \vdots  h_M  w_M       Output Print the answer.        Sample Input 1 2 3 3
2 2
1 1
1 3      Sample Output 1 3  We can destroy all the targets by placing the bomb at \left(1, 2\right) .       Sample Input 2 3 3 4
3 3
3 1
1 1
1 2      Sample Output 2 3       Sample Input 3 5 5 10
2 5
4 3
2 3
5 5
2 2
5 4
5 3
5 1
3 5
1 4      Sample Output 3 6

Solution (Python):
from itertools import product
h, w, m = map(int, input().split())


row = [set()for _ in range(h)]
col = [set()for _ in range(w)]
for _ in range(m):
    x, y = map(lambda x: int(x)-1, input().split())
    row[x].add(y)
    col[y].add(x)

crow = 0
ic = []
for i, x in enumerate(row):
    if crow < len(x):
        crow = len(x)
        ic = [i]
    elif crow == len(x):
        ic.append(i)

ccol = 0
jc = []
for j, x in enumerate(col):
    if ccol < len(x):
        ccol = len(x)
        jc = [j]
    elif ccol == len(x):
        jc.append(j)


ans = crow+ccol
for i, j in product(ic, jc):
    if j not in row[i]:
        print(ans)
        break
else:
    print(ans-1)

Solution (Python):
import sys
from copy import deepcopy as copy
input = sys.stdin.readline


def main():
    h, w, m = map(int, input().split())
    
    bomb_h = [0]*h
    bomb_w = [0]*w
    bomb_w_place = [set() for _ in range(w)]
    for i in range(m):
        x, y = map(int, input().split())
        bomb_h[x-1] += 1
        bomb_w[y-1] += 1
        bomb_w_place[y-1].add(x-1)
    bomb_h2 = [0]*h
    for i in range(h):
        bomb_h2[i] = [bomb_h[i], i]
    bomb_h2.sort(reverse=True)
    
    ans = 0
    for i in range(w):
        index = 0
        key = bomb_w[i]
        k1, k2 = True, True
        ma = -1
        while index < len(bomb_h2):
            key2 = bomb_h2[index]
            if key2[1] in bomb_w_place[i]:
                if ma == -1:
                    ma = key2[0]-1
                    index += 1
                    continue
                elif ma == key2[0]-1:
                    index += 1
                    continue
                else:
                    break
            else:
                ma = max(ma, key2[0])
                break
            index += 1
        
        ans = max(ans, key+ma)
    print(ans)
        
    
    
if __name__ == "__main__":
    main()

Solution (Python):
import sys
read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
from heapq import heappop,heappush

H,W,M = map(int,readline().split())
hw = list(map(int,read().split()))

x_num = [0] * (H+1)
y_num = [0] * (W+1)

it = iter(hw)
for h,w in zip(it,it):
    x_num[h] += 1
    y_num[w] += 1

x_max = max(x_num)
y_max = max(y_num)

x_max_set = set()
y_max_set = set()
for i,num in enumerate(x_num):
    if(num == x_max):
        x_max_set.add(i)

for i,num in enumerate(y_num):
    if(num == y_max):
        y_max_set.add(i)

cnt = 0
it = iter(hw)
for h,w in zip(it,it):
    if(h in x_max_set)&(w in y_max_set):
        cnt += 1

point = len(x_max_set) * len(y_max_set)
ans = x_max+y_max
if(point == cnt):
    ans -= 1
print(ans)

Solution (Python):
H, W, M = map(int, input().split())
test = [[i, i] for i in range(1, M+1)]
tH, tW, tag = [0]*H, [0]*W, set()
Hmax, Wmax = 0, 0

for _ in range(M):
    h, w = map(int, input().split())
    tH[h-1] += 1
    tW[w-1] += 1
    tag.add(W*(h-1) + (w-1))
    Hmax = max(Hmax, tH[h-1])
    Wmax = max(Wmax, tW[w-1])

Hind = [i for i, x in enumerate(tH) if x == Hmax]
Wind = [i for i, x in enumerate(tW) if x == Wmax]
if len(Hind) * len(Wind) > M:
    print(Hmax + Wmax)
    exit()
else:
    for h in Hind:
        for w in Wind:
            if W*h + w not in tag:
                print(Hmax + Wmax)
                exit()
print(Hmax + Wmax - 1)

Solution (Python):
from collections import defaultdict
def main():
    H, W, M = map( int, input().split())
    HW = [ tuple( map( int, input().split())) for _ in range(M)]
    R = [0]*H
    C = [0]*W
    d = defaultdict( lambda : False)
    for h, w in HW:
        R[h-1] += 1
        C[w-1] += 1
        d[(h-1,w-1)] = True
    MR = max(R)
    MC = max(C)
    ans = MR+MC-1
    NR = []
    NC = []
    for index, r in enumerate(R):
        if r == MR:
            NR.append(index)
    for index, c in enumerate(C):
        if c == MC:
            NC.append(index)
    
    
    
    for r in NR:
        for c in NC:
            if not d[(r,c)]:
                
                print(ans+1)
                return
    print(ans)
    
    
if __name__ == '__main__':
    main()

Solution (Python):
"""
    Satwik_Tiwari ;) .
    21st AUGUST , 2020  - FRIDAY
"""



from __future__ import division, print_function

from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase

from itertools import *
import bisect
from heapq import *
from math import *
from copy import *
from collections import deque
from collections import Counter as counter  
from itertools import combinations as comb 
from itertools import permutations as permutate
from bisect import bisect_left as bl


from bisect import bisect_right as br
from bisect import bisect





BUFSIZE = 8192


class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)


class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")


def print(*args, **kwargs):
    """Prints the values to a stream, or to sys.stdout by default."""
    sep, file = kwargs.pop("sep", " "), kwargs.pop("file", sys.stdout)
    at_start = True
    for x in args:
        if not at_start:
            file.write(sep)
        file.write(str(x))
        at_start = False
    file.write(kwargs.pop("end", "\n"))
    if kwargs.pop("flush", False):
        file.flush()


if sys.version_info[0] < 3:
    sys.stdin, sys.stdout = FastIO(sys.stdin), FastIO(sys.stdout)
else:
    sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)





from types import GeneratorType
def iterative(f, stack=[]):
  def wrapped_func(*args, **kwargs):
    if stack: return f(*args, **kwargs)
    to = f(*args, **kwargs)
    while True:
      if type(to) is GeneratorType:
        stack.append(to)
        to = next(to)
        continue
      stack.pop()
      if not stack: break
      to = stack[-1].send(to)
    return to
  return wrapped_func





mod = 1000000007
def inp(): return sys.stdin.readline().rstrip("\r\n") 
def out(var): sys.stdout.write(str(var))  
def lis(): return list(map(int, inp().split()))
def stringlis(): return list(map(str, inp().split()))
def sep(): return map(int, inp().split())
def strsep(): return map(str, inp().split())

def zerolist(n): return [0]*n
def nextline(): out("\n")  
def testcase(t):
    for p in range(t):
        solve()
def printlist(a) :
    for p in range(0,len(a)):
        out(str(a[p]) + ' ')
def google(p):
    print('Case 
def lcm(a,b): return (a*b)//gcd(a,b)
def power(x, y, p) :
    res = 1     
    x = x % p  
    if (x == 0) :
        return 0
    while (y > 0) :
        if ((y & 1) == 1) : 
            res = (res * x) % p

        y = y >> 1      
        x = (x * x) % p
    return res
def ncr(n,r): return factorial(n)//(factorial(r)*factorial(max(n-r,1)))
def isPrime(n) :
    if (n <= 1) : return False
    if (n <= 3) : return True
    if (n % 2 == 0 or n % 3 == 0) : return False
    i = 5
    while(i * i <= n) :
        if (n % i == 0 or n % (i + 2) == 0) :
            return False
        i = i + 6
    return True



@iterative
def dfs(v,visited,st,new):
    new.append(st)
    visited[st] = 1
    for i in v[st]:
        if(visited[i] == 0):
            ok = yield dfs(v,visited,i,new)
    yield True


def solve():
    n,m,p = sep()

    row = [0]*n
    col = [0]*m
    have = {}
    for i in range(p):
        a,b = sep()
        a-=1
        b-=1
        have[str(a)+' '+str(b)] = 1
        row[a] +=1
        col[b] +=1

    rmx = max(row)
    cmx = max(col)
    total = row.count(rmx)*col.count(cmx)
    ans = 0
    for i in have:
        ind = i.index(' ')
        a = int(i[:ind])
        b = int(i[ind+1:])
        if(row[a]==rmx and col[b] == cmx):
            ans +=1

    if(total==ans):
        print(rmx+cmx-1)
    else:
        print(rmx+cmx)










testcase(1)

Solution (Python):
import sys
from collections import Counter


def main():
    input = sys.stdin.buffer.readline
    h, w, m = map(int, input().split())
    h = [0] * m
    w = [0] * m
    object_set = set()
    for i in range(m):
        h[i], w[i] = map(int, input().split())
        object_set.add((h[i], w[i]))
    h_counter = Counter(h)
    w_counter = Counter(w)
    max_h_num = h_counter.most_common()[0][1]
    max_w_num = w_counter.most_common()[0][1]
    ans = max_h_num + max_w_num

    h_cand = set()
    w_cand = set()
    for e, n in h_counter.most_common():
        if n == max_h_num:
            h_cand.add(e)
    for e, n in w_counter.most_common():
        if n == max_w_num:
            w_cand.add(e)

    cnt = 0
    for h_e, w_e in object_set:
        if h_e in h_cand and w_e in w_cand:
            cnt += 1

    print(ans if cnt < len(h_cand) * len(w_cand) else ans - 1)


if __name__ == "__main__":
    main()

Solution (Python):
def argmaxs(lst):
    mx=max(lst)
    output=[]
    for i,a in enumerate(lst):
        if a==mx:
            output.append(i)
    
    return output
    
def main():
    import sys
    H,W,M=list(map(int,sys.stdin.readline().split()))
    y_lst=[0]*H
    x_lst=[0]*W
    bumbs=[set() for _ in range(H)]

    for i in range(M):
        h,w=list(map(int,sys.stdin.readline().split()))
        y_lst[h-1]+=1
        x_lst[w-1]+=1
        bumbs[h-1].add(w-1)

    output=max(x_lst)+max(y_lst)
    
    
    argys=argmaxs(y_lst)
    argxs=argmaxs(x_lst)
    argx_set=set(argxs)

    k=1
    for y in argys:
        if not(argx_set <= bumbs[y]):
            k=0
            break

    
    print(output-k)
main()

Solution (Python):
def f():
    for i in R:
        for j in C:
            try:
                if d[(i,j)]:
                    pass
            except:
                return 1
    return 0

h,w,m=map(int,input().split())
r=[0 for i in range(h)]
c=[0 for i in range(w)]
t=[]
d={}
for i in range(m):
    x,y=map(int,input().split())
    d[(x-1,y-1)]=True
    r[x-1]+=1
    c[y-1]+=1
r_=max(r)
c_=max(c)
R=[]
C=[]
for i in range(h):
    if r[i]==r_:
        R.append(i)
for i in range(w):
    if c[i]==c_:
        C.append(i)

flag=f()
if flag:
    print(r_+c_)
else:
    print(r_+c_-1)

Solution (Python):

from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def I(): return int(sys.stdin.readline())
def LS():return [list(x) for x in sys.stdin.readline().split()]
def S():
    res = list(sys.stdin.readline())
    if res[-1] == "\n":
        return res[:-1]
    return res
def IR(n):
    return [I() for i in range(n)]
def LIR(n):
    return [LI() for i in range(n)]
def SR(n):
    return [S() for i in range(n)]
def LSR(n):
    return [LS() for i in range(n)]

sys.setrecursionlimit(1000000)
mod = 1000000007

def solve():
    h,w,m = LI()
    fx = [0]*w
    fy = [0]*h
    f = defaultdict(lambda : 0)
    for _ in range(m):
        y,x = LI()
        y -= 1
        x -= 1
        f[(y,x)] = 1
        fx[x] += 1
        fy[y] += 1
    m = 0
    lisx = []
    for x in range(w):
        srx = fx[x]
        if m < srx:
            m = srx
    for x in range(w):
        srx = fx[x]
        if m == srx:
            lisx.append(x)
    M = 0
    lisy = []
    for y in range(h):
        srx = fy[y]
        if M < srx:
            M = srx
    for y in range(h):
        srx = fy[y]
        if M == srx:
            lisy.append(y)
    ans = m+M
    for y in lisy:
        for x in lisx:
            if not f[(y,x)]:
                print(ans)
                return
    print(ans-1)
    return


if __name__ == "__main__":
    solve()

Solution (Python):
H,W,M=map(int,input().split())
A=[0 for i in range(H+1)]
B=[0 for i in range(W+1)]
N=[]
for i in range(M):
    h,w=map(int,input().split())
    A[h]+=1
    B[w]+=1
    N.append([h,w])
max_A=[]
max_value_A=0
for i in range(1,len(A)):
    if A[i]>max_value_A:
        max_value_A=A[i]
        max_A=[i]                   
    elif A[i]==max_value_A:
        max_A.append(i)
maxA=[0 for i in range(len(A))]
for i in max_A:
    maxA[i]+=1
max_B=[]
max_value_B=0
for j in range(1,len(B)):
    if B[j]>max_value_B:
        max_value_B=B[j]
        max_B=[j]
    elif B[j]==max_value_B:
        max_B.append(j)
maxB=[0 for i in range(len(B))]
for j in max_B:
    maxB[j]+=1
count=0
for i,j in N:
    if maxA[i]==1 and maxB[j]==1:
        count+=1
flag=0
if count==len(max_A)*len(max_B):
    flag=1
print(max_value_A+max_value_B-flag)

Solution (Python):
import collections as cc
import sys
import bisect as bi
I=lambda:list(map(int,input().split()))
a,b,m=I()
ar=[I() for i in range(m)]
row=cc.defaultdict(int)
col=cc.defaultdict(int)
rr=cc.defaultdict(int)
ccc=cc.defaultdict(int)
for i in ar:
	rr[i[0]]+=1
	ccc[i[1]]+=1
	row[tuple(i)]=1
rc=max(rr.values())
cr=max(ccc.values())
p=[i for i in rr if rr[i]==rc]
q=[i for i in ccc if ccc[i]==cr]
ans=rc+cr
tf=0
for i in p:
	for j in q:
		if row[(i,j)]==0:
			tf=1
			break
	if tf:
		break
if tf==0:
	ans-=1
print(ans)

Solution (Python):
H, W, M = map(int, input().split())
target = [tuple(map(lambda x:int(x) - 1, input().split())) for _ in range(M)]

X = [0 for _ in range(H)]
Y = [0 for _ in range(W)]

for i in range(M):
    h, w = target[i]
    X[h] += 1
    Y[w] += 1

xmax = max(X)
ymax = max(Y)

xlist = set()
ylist = set()

for i in range(H):
    if X[i] == xmax:
        xlist.add(i)

for i in range(W):
    if Y[i] == ymax:
        ylist.add(i)

tmp = 0

for h, w in target:
    if h in xlist and w in ylist:
        tmp += 1

if len(xlist) * len(ylist) == tmp:
    print(xmax + ymax - 1)
else:
    print(xmax + ymax)

Solution (Python):
import heapq
def main():
    H, W, M = map(int, input().split())

    bn_h = {}
    bn_v = {}

    for i in range(M):
        h, w = map(int, input().split())
        bn_h.setdefault(h, set())
        bn_h[h].add(w)
        bn_v.setdefault(w, set())
        bn_v[w].add(h)

    b1 = sorted(bn_h.items(), key = lambda x:len(x[1]), reverse=True)
    b2 = sorted(bn_v.items(), key = lambda x:len(x[1]), reverse=True)

    m1 = len(b1[0][1])
    m2 = len(b2[0][1])

    flag = False
    max_result = 0
    for i in b1:
        h, sh = i
        if len(sh) < m1:
            break
        for j in b2:
            v, sv = j
            if len(sv) < m2:
                break
            result = len(sh) + len(sv) - 1
            if h not in sv:
                result += 1
                flag = True
            max_result = max(max_result, result)
            if flag == True:
                break
        if flag == True:
            break
    print(max_result)

if __name__ == '__main__':
    main()

Solution (Python):
H,W,M = map(int,input().split())
hw = [list(map(int,input().split())) for _ in range(M)]

dh = {}
dw = {}
for i in range(M):
    h,w = hw[i]
    if h not in dh:
        dh[h] = 0
    dh[h] += 1
    if w not in dw:
        dw[w] = 0
    dw[w] += 1

mh = 0
mw = 0
for h in dh:
    mh = max(mh,dh[h])
hcand = []
for h in dh:
    if dh[h]==mh:
        hcand.append(h)

for w in dw:
    mw = max(mw,dw[w])
wcand = []
for w in dw:
    if dw[w]==mw:
        wcand.append(w)

n_cand = len(hcand)*len(wcand)
for i in range(M):
    h,w = hw[i]
    if dh[h]==mh and dw[w]==mw:
        n_cand -= 1

if n_cand>0:
    ans = mh+mw
else:
    ans = mh+mw-1

print(ans)

Solution (Python):
H, W, M = map(int, input().split())
hk = [[0, i] for i in range(H + 1)]
wk = [[0, j] for j in range(W + 1)]
s = set()
for i in range(M):
    h, w = map(int, input().split())
    hk[h][0] += 1
    wk[w][0] += 1
    s.add((h, w))
hk.sort(reverse=True)
wk.sort(reverse=True)
colmax = wk[0][0]
ans = 0
for lowacc, i in hk:
    if lowacc + colmax <= ans:
        break
    for colacc, j in wk:
        if lowacc + colacc <= ans:
            break
        else:
            ans = max(ans, lowacc + colacc - ((i, j) in s))
print(ans)

Solution (Python):
from collections import defaultdict
H, W, M = map(int, input().split())
hs = defaultdict(int)
ws = defaultdict(int)
expl = set()

for i in range(M):
    h, w = map(int, input().split())
    hs[h] += 1
    ws[w] += 1
    expl.add((h, w))

hscan = []
wscan = []
hmax = max(hs.values())
wmax = max(ws.values())

for i, m in hs.items():
    if m == hmax:
        hscan.append(i)

for i, m in ws.items():
    if m == wmax:
        wscan.append(i)

for h in hscan:
    for w in wscan:
        if not (h, w) in expl:
            print(hmax + wmax)
            exit()

print(hmax + wmax - 1)

Solution (Python):
from collections import defaultdict
import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)

H, W, M = map(int, input().split())
row = [0] * (H + 1)
col = [0] * (W + 1)

hw = []
d = defaultdict(int)

for _ in range(M):
    h, w = map(int, input().split())
    d[(h, w)] = 1
    row[h] += 1
    col[w] += 1

r_max = 0
ri = []
c_max = 0
ci = []

for i, cnt in enumerate(col):
    if not cnt:
        continue
    if cnt > c_max:
        c_max = cnt
        ci = [i]
    elif cnt == c_max:
        ci.append(i)

for i, cnt in enumerate(row):
    if not cnt:
        continue
    if cnt > r_max:
        r_max = cnt
        ri = [i]
    elif cnt == r_max:
        ri.append(i)

ans = c_max + r_max


for r in ri:
    for c in ci:
        if not d[(r, c)]:
            print(ans)
            exit()

print(ans - 1)

Solution (Python):
import sys
input = sys.stdin.readline

H,W,M=map(int,input().split())
B=set([tuple(map(int,input().split())) for i in range(M)])

HH=[0]*(H+1)
WW=[0]*(W+1)

for x,y in B:
    HH[x]+=1
    WW[y]+=1

MAXH=max(HH)
MAXW=max(WW)

ANS=MAXH+MAXW-1

HLIST=[]
WLIST=[]
for i in range(1,H+1):
    if HH[i]==MAXH:
        HLIST.append(i)

for j in range(1,W+1):
    if WW[j]==MAXW:
        WLIST.append(j)

for i in HLIST:
    for j in WLIST:
        if (i,j) in B:
            continue
        else:
            print(ANS+1)
            sys.exit()
print(ANS)

Solution (Python):
import sys

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 19
MOD = 10 ** 19 + 7
EPS = 10 ** -10

class BIT:
    """ BIT汎用版 """

    def __init__(self, n, func, init):
        
        n += 1
        nv = 1
        while nv < n:
            nv *= 2
        self.size = nv
        self.func = func
        self.init = init
        self.tree = [init] * nv
    
    def query(self, i):
        """ [0, i]の値を取得 """
        s = self.init
        i += 1
        while i > 0:
            s = self.func(s, self.tree[i-1])
            i -= i & -i
        return s
    
    def update(self, i, x):
        """ 値の更新：添字i, 値x """
        i += 1
        while i <= self.size:
            self.tree[i-1] = self.func(self.tree[i-1], x)
            i += i & -i


class SegTree:
    """
    セグメント木
    1.update: i番目の値をxに更新する
    2.query: 区間[l, r)の値を得る
    """

    def __init__(self, n, func, intv, A=[]):
        """
        :param n: 要素数(0-indexed)
        :param func: 値の操作に使う関数(min, max, add, gcdなど)
        :param intv: 要素の初期値(単位元)
        :param A: 初期化に使うリスト(オプション)
        """
        self.n = n
        self.func = func
        self.intv = intv
        n2 = 1
        while n2 < n:
            n2 <<= 1
        self.n2 = n2
        self.tree = [self.intv] * (n2 << 1)
        if A:
            for i in range(n):
                self.tree[n2+i] = A[i]
            for i in range(n2-1, -1, -1):
                self.tree[i] = self.func(self.tree[i*2], self.tree[i*2+1])

    def update(self, i, x):
        """
        i番目の値をxに更新
        :param i: index(0-indexed)
        :param x: update value
        """
        i += self.n2
        self.tree[i] = x
        while i > 0:
            i >>= 1
            self.tree[i] = self.func(self.tree[i*2], self.tree[i*2+1])

    def add(self, i, x):
        self.update(i, self.get(i) + x)

    def query(self, a, b):
        """
        [a, b)の値を得る
        :param a: index(0-indexed)
        :param b: index(0-indexed)
        """
        l = a + self.n2
        r = b + self.n2
        s = self.intv
        while l < r:
            if r & 1:
                r -= 1
                s = self.func(s, self.tree[r])
            if l & 1:
                s = self.func(s, self.tree[l])
                l += 1
            l >>= 1
            r >>= 1
        return s

    def get(self, i):
        """ 一点取得 """
        return self.tree[i+self.n2]

    def all(self):
        """ 全区間[0, n)の取得 """
        return self.tree[1]

    def print(self):
        for i in range(self.n):
            print(self.get(i), end=' ')
        print()

H, W, M = MAP()
seg = SegTree(W+1, max, -INF, [0]*(W+1))
adjli = [[] for i in range(H+1)]
C = [0] * (W+1)
for i in range(M):
    h, w = MAP()
    seg.add(w, 1)
    adjli[h].append(w)

ans = 0
for h in range(1, H+1):
    rowcnt = len(adjli[h])
    for w in adjli[h]:
        seg.add(w, -1)
    ans = max(ans, rowcnt+seg.all())
    for w in adjli[h]:
        seg.add(w, 1)
print(ans)

Solution (Python):
h, w, m = map(int, input().split())

target = set()
rows = [0] * h
cols = [0] * w
for i in range(m):
    y, x = map(lambda x: int(x) - 1, input().split())
    rows[y] += 1
    cols[x] += 1
    target.add((y, x))

rows_sorted = [(a, i) for i, a in enumerate(rows)]
rows_sorted.sort(reverse=True)
cols_sorted = [(a, i) for i, a in enumerate(cols)]
cols_sorted.sort(reverse=True)

max_r = rows_sorted[0][0]
max_c = cols_sorted[0][0]

i = 0
max_val = max(max_r, max_c)
while i < h and rows_sorted[i][0] == max_r:
    j = 0
    while j < w and cols_sorted[j][0] == max_c:
        val = rows_sorted[i][0] + cols_sorted[j][0]
        if (rows_sorted[i][1], cols_sorted[j][1]) in target:
            val -= 1
        else:
            max_val = val
            break
        max_val = max(max_val, val)
        j += 1
    i += 1
print(max_val)

Solution (Python):

def get_count(li,c):
    if(li==[]):
        return ((0,0))
    m=(li[0][c],1)
    h={}
    h[li[0][c]]=1
    for i in li[1:]:
        if(i[c] in h):
            h[i[c]]+=1
        else:
            h[i[c]]=1
        if(m[1]<h[i[c]]):
            m=(i[c],h[i[c]])
    return m


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

if(h==1 or w==1 or n<=1):
    li = []
    for i in range(n):
        li.append(tuple(map(int, input().split())))
    print(n)
else:
    li=[]
    for i in range(n):
        li.append(tuple(map(int,input().split())))
    li=list(set(li))
    r=get_count(li,0)
    c=get_count(li,1)
    
    s=0
    if(r[1]>c[1]):
        temp=[]
        for i in li:
            if(i[0]!=r[0]):
                temp.append(i)
        s+=r[1]+get_count(temp,1)[1]
    else:
        temp=[]
        for i in li:
            if(i[1]!=c[0]):
                temp.append(i)
        s+=c[1]+get_count(temp,0)[1]

    print(s)

Solution (Python):
import sys
from collections import Counter
input = lambda : sys.stdin.readline().rstrip()

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

xs = []
ys = []
for i in range(m):
    x, y = map(int, input().split(" "))
    xs.append(x)
    ys.append(y)

xcounter = Counter(xs)
ycounter = Counter(ys)

x_most, x_most_num = xcounter.most_common(1)[0]








out1 = x_most_num

if x_most_num < m:
    y2s = [] 
    for i in range(m):
        if xs[i] == x_most:
            continue
        else:  
            y2s.append(ys[i])
        
    y2counter = Counter(y2s)
    y2_most, y2_most_num = y2counter.most_common(1)[0]
    out1 += y2_most_num


y_most, y_most_num = ycounter.most_common(1)[0]

out2 = y_most_num

if y_most_num < m:
    x2s = [] 
    for i in range(m):
        if ys[i] == y_most:
            continue
        else:  
            x2s.append(xs[i])
        
    x2counter = Counter(x2s)
    x2_most, x2_most_num = x2counter.most_common(1)[0]
    out2 += x2_most_num

out = max(out1, out2)

print(out)

Solution (Python):
H, W, M = map(int, input().split())

A = [0 for _ in range(H)]
B = [0 for _ in range(W)]
C = set()

for _ in range(M):
  h, w = map(int, input().split())
  A[h-1] += 1
  B[w-1] += 1
  C.add((h-1, w-1))
  
d = max(A)
e = max(B)
ans = d+e

F = set()
G = set()
for h in range(H):
  if A[h] == d:
    F.add(h)
for w in range(W):
  if B[w] == e:
    G.add(w)
  
spot = len(F)*len(G)
spt_bm = 0

for c in C:
  if c[0] in F and c[1] in G:
    
    spt_bm += 1
    
if spt_bm == spot:
  ans -= 1
  



print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**7) 
import math
from copy import copy, deepcopy
from copy import deepcopy as dcp
from operator import itemgetter
from bisect import bisect_left, bisect, bisect_right

from collections import deque, defaultdict


from collections import Counter

from itertools import accumulate,combinations,permutations,product

from heapq import heapify,heappop,heappush

from functools import reduce,lru_cache

from decimal import Decimal
from argparse import ArgumentParser

args=ArgumentParser()
args.add_argument('-loc', '--local', type=bool,default=False)
LOCAL=args.parse_args().local

def input(): 
    x=sys.stdin.readline(); 
    if x[-1]=="\n": 
        return x.rstrip() 
    return x
    
def printe(*x):_=print("
def printl(li): _=print(*li, sep="\n") if li else None
def argsort(s, return_sorted=False): 
    inds=sorted(range(len(s)), key=lambda k: s[k])
    if return_sorted: return inds, [s[i] for i in inds]
    return inds
def alp2num(c,cap=False): return ord(c)-97 if not cap else ord(c)-65
def num2alp(i,cap=False): return chr(i+97) if not cap else chr(i+65)
def matmat(A,B):
    K,N,M=len(B),len(A),len(B[0])
    return [[sum([(A[i][k]*B[k][j]) for k in range(K)]) for j in range(M)] for i in range(N)]
def matvec(M,v):
    N,size=len(v),len(M)
    return [sum([M[i][j]*v[j] for j in range(N)]) for i in range(size)]
def T(M):
    n,m=len(M),len(M[0])
    return [[M[j][i] for j in range(n)] for i in range(m)]
def binr(x): return bin(x)[2:]
def bitcount(x): 
    x= x - ((x >> 1) & 0x5555555555555555)
    x= (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333)
    x= (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f 
    x+= (x >> 8); x+= (x >> 16); x+= (x >> 32) 
    return x & 0x7f

class segtree():
    def __init__(self,A,ide=0):
        n=len(A)
        num=2**(n-1).bit_length()
        seg=[ide]*(2*num-1)
        segfunc=self.segfunc
        self.ide,self.n,self.num,self.seg = ide, n, num, seg
        for i in range(n): seg[i+num-1]=A[i]
        for i in range(num-2,-1,-1):seg[i]=segfunc(seg[2*i+1],seg[2*i+2])
    
    def segfunc(self,x,y):return max(x,y) 
    
    def update(self,k,x):
        k += self.num-1
        seg,segfunc=self.seg,self.segfunc
        seg[k] = x
        while k:
            k = (k-1)//2
            seg[k] = segfunc(seg[k*2+1],seg[k*2+2])
    
    def query(self,p,q):
        if q<=p: return self.ide
        num,segfunc,seg=self.num,self.segfunc,self.seg
        p += num-1; q += num-2
        res=self.ide
        while q-p>1:
            if p&1 == 0: res = segfunc(res,seg[p])
            if q&1 == 1:
                res = segfunc(res,seg[q])
                q -= 1
            p,q = p//2, (q-1)//2
        if p == q: res = segfunc(res,seg[p])
        else: res = segfunc(segfunc(res,seg[p]),seg[q])
        return res 

def main():
    mod = 1000000007
    

    
    H,W,M = map(int, input().split())
    
    
    S = tuple(tuple(map(int, input().split())) for i in range(M)) 

    lis=[set() for _ in range(H)]
    l=[0]*W
    seg=segtree(l)
    
    for h,w, in S:
        h-=1
        w-=1
        lis[h].add(w)
        if h!=0:
            l[w]+=1
            seg.update(w,l[w])
    ans=0
    for h in range(H):
        ans=max(ans,seg.query(0,W)+len(lis[h]))

        if h==H-1:
            break
        for w in lis[h]:
            l[w]+=1
            seg.update(w,l[w])
        for w in lis[h+1]:
            l[w]-=1
            seg.update(w,l[w])
    print(ans)
    
            



if __name__ == "__main__":
    main()

Solution (Python):
import sys

def solve():
    input = sys.stdin.readline
    H, W, M = map(int, input().split())
    Bomb = dict()
    Hc = [0] * H
    Wc = [0] * W
    for _ in range(M):
        h, w = map(int, input().split())
        Bomb[(h-1, w-1)] = 0
        Hc[h-1] += 1
        Wc[w-1] += 1
    maxH, maxW = max(Hc), max(Wc)
    maxHs = []
    for i, h in enumerate(Hc):
        if h == maxH: maxHs.append(i)
    maxWs = []
    for i, w in enumerate(Wc):
        if w == maxW: maxWs.append(i)
    
    ans = maxH + maxW - 1
    for h in maxHs:
        for w in maxWs:
            if (h, w) not in Bomb:
                ans += 1
                break
        if ans == maxH + maxW:
            break
    print(ans)

    return 0

if __name__ == "__main__":
    solve()