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):
class SegmentTree:
    def __init__(self, init_val, segfunc, ide_ele):
        n = len(init_val)
        self.segfunc = segfunc
        self.ide_ele = ide_ele
        self.num = 1 << (n - 1).bit_length()
        self.tree = [ide_ele] * 2 * self.num
        
        for i in range(n):
            self.tree[self.num + i] = init_val[i]
        
        for i in range(self.num - 1, 0, -1):
            self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

    def update(self, k, x):
        k += self.num
        self.tree[k] = x
        while k > 1:
            self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
            k >>= 1

    def query(self, l, r):
        res = self.ide_ele

        l += self.num
        r += self.num
        while l < r:
            if l & 1:
                res = self.segfunc(res, self.tree[l])
                l += 1
            if r & 1:
                res = self.segfunc(res, self.tree[r - 1])
            l >>= 1
            r >>= 1
        return res

import sys,random

input=sys.stdin.readline

H,W,M=map(int,input().split())
bomb=[[] for i in range(H)]
row=[0 for i in range(H)]
column=[0 for j in range(W)]

for _ in range(M):
    h,w=map(int,input().split())
    
    row[h-1]+=1
    column[w-1]+=1
    bomb[h-1].append(w-1)


for i in range(H):
    bomb[i].sort()

Seg=SegmentTree(column,segfunc=max,ide_ele=0)

ans=0
for i in range(H):
    for j in range(len(bomb[i])-1):
        L,R=bomb[i][j],bomb[i][j+1]
        tmp=row[i]+max(column[L],column[R])-1
        ans=max(ans,tmp)
        L+=1
        if L==R:
            continue
        tmp=row[i]+Seg.query(L,R)
        ans=max(ans,tmp)
    if bomb[i] and bomb[i][0]!=0:
        L,R=0,bomb[i][0]
        tmp=row[i]+Seg.query(L,R)
        ans=max(ans,tmp)
    if bomb[i] and bomb[i][-1]!=W-1:
        L,R=bomb[i][-1]+1,W
        tmp=row[i]+Seg.query(L,R)
        ans=max(ans,tmp)
    if not bomb[i]:
        tmp=row[i]+Seg.query(0,W)
        ans=max(ans,tmp)
    else:
        tmp=row[i]+column[bomb[i][0]]-1
        ans=max(ans,tmp)

print(ans)

Solution (Python):

import sys
from collections import defaultdict

H, W, M = map(int, input().split())
X = [list(map(int, input().split())) for _ in range(M)]

ctr_h = defaultdict(int)
ctr_w = defaultdict(int)
appeared = set()

for h, w in X:
    ctr_h[h] += 1
    ctr_w[w] += 1
    appeared.add(h * W + w)

val_h = sorted(ctr_h.items(), key=lambda x: -x[1])
val_w = sorted(ctr_w.items(), key=lambda x: -x[1])

max_h = val_h[0][1]
max_w = val_w[0][1]

val_h = [i for i, v in val_h if v == max_h]
val_w = [i for i, v in val_w if v == max_w]

if len(val_h) * len(val_w) > M:
    print(max_h + max_w)
    sys.exit(0)

for h in val_h:
    for w in val_w:
        if h * W + w not in appeared:
            print(max_h + max_w)
            sys.exit(0)
else:
    print(max_h + max_w - 1)

Solution (Python):
h,w,m = map(int, input().split())
row = [0]*(h+1)
rn = [[] for _ in range(h+1)]
col = [0]*(w+1)
cn = [[] for _ in range(w+1)]
data = []
for _ in range(m):
  hd,wd = map(int, input().split())
  row[hd] += 1
  rn[hd].append(wd)
  col[wd] += 1
  cn[wd].append(hd)

cm = max(col)
rm = max(row)
ri = [x for x,y in enumerate(row) if y == rm]
ci = [x for x,y in enumerate(col) if y == cm]
for r in ri:
  rs = set(rn[r])
  for c in ci:
    if c not in rs:
      ans = cm+rm
      print(ans)
      exit()
ans = cm+rm-1
print(ans)

Solution (Python):
import sys

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

h_bomb = [0 for _ in range(h)]
w_bomb = [0 for _ in range(w)]

bomb_xy = {}
for ij in range(m):
    y, x = map(int, input().split())
    h_bomb[y-1] += 1
    w_bomb[x-1] += 1
    bomb_xy[str(y-1)+str(x-1)] = 1

h_max = max(h_bomb)
h_max_index = [i for i, y in enumerate(h_bomb) if y == h_max]
w_max = max(w_bomb)
w_max_index = [j for j, x in enumerate(w_bomb) if x == w_max]

ans = 0

for j in h_max_index:
    for i in w_max_index:
        if str(j)+str(i) in bomb_xy:
            ans = h_bomb[j] + w_bomb[i] - 1
        else:
            print(h_bomb[j] + w_bomb[i])
            sys.exit()

print(ans)

Solution (Python):
import sys
h,w,m=map(int,input().split())
bomb_h = [0]*h
bomb_w = [0]*w
place = list()

for _ in range(m):
  x,y=map(int,input().split())
  bomb_h[x-1]+=1
  bomb_w[y-1]+=1
  place.append([x-1,y-1])
x_cand = list()
x_max = 0

for x in range(h):
  if x_max < bomb_h[x]:
    x_cand = [x]
    x_max = bomb_h[x]
  elif x_max == bomb_h[x]:
    x_cand.append(x)
y_cand = list()
y_max = 0

for y in range(w):
  if y_max < bomb_w[y]:
    y_cand = [y]
    y_max = bomb_w[y]
  elif y_max == bomb_w[y]:
    y_cand.append(y)
ans = x_max+y_max

cnt = 0

for p in place:
  if bomb_h[p[0]]== x_max and bomb_w[p[1]]==y_max:
    cnt += 1
if len(x_cand)*len(y_cand) > cnt:
  print(ans)
else:
  print(ans-1)

Solution (Python):
from operator import itemgetter

h, w, m = (int(x) for x in input().split())
H = [0] * h
W = [0] * w
HW = []
for _ in range(m):
    h_, w_ = (int(x) - 1 for x in input().split())
    HW.append((h_, w_))
    H[h_] += 1
    W[w_] += 1
hmax = max(H)
wmax = max(W)
hindex = set()
windex = set()

HW.sort(key=itemgetter(0, 1))
for y in range(h):
    if H[y] == hmax:
        hindex.add(y)
for x in range(w):
    if W[x] == wmax:
        windex.add(x)

count = 0
for h, w in HW:
    if h in hindex and w in windex:
        count += 1

if count == len(hindex)*len(windex):
    ans = hmax + wmax - 1
else:
    ans = hmax + wmax

print(ans)

Solution (Python):
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

import heapq

def main():
    H, W, M = map(int, readline().split())
    m = map(int,read().split())
    hw = list(zip(m,m))

    row_bombers = [0] * (H+1)
    col_bombers = [0] * (W+1)

    for (h, w) in hw:
        row_bombers[h] += 1
        col_bombers[w] += 1

    row_max = max(row_bombers)
    col_max = max(col_bombers)

    max_rows = [i for i in range(H+1) if row_bombers[i] == row_max]
    max_cols = [i for i in range(W+1) if col_bombers[i] == col_max]

    ans = row_max + col_max
    
    num_empty_cells_in_kouho = len(max_rows) * len(max_cols)
    for (h, w) in hw:
        if row_bombers[h] == row_max and col_bombers[w] == col_max:
            num_empty_cells_in_kouho -= 1

    if num_empty_cells_in_kouho == 0:
        ans -= 1
    
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
h, w, m = map(int, input().split())
H = [0] * (h+1)
W = [0] * (w+1)
bombs = set()
for _ in range(m):
    hh, ww = map(lambda x: int(x)-1, input().split())
    H[hh] += 1
    W[ww] += 1
    bombs.add((hh, ww))

mh = max(H)
mw = max(W)
mhis = [i for i, x in enumerate(H) if x == mh]
mwis = [i for i, x in enumerate(W) if x == mw]

duplicated = True
for mhi in mhis:
    for mwi in mwis:
        if not (mhi, mwi) in bombs:
            duplicated = False
            break
            
ans = mh + mw - duplicated
print(ans)

Solution (Python):
import sys,bisect

from sys  import stdin,stdout

from bisect import bisect_left,bisect_right,bisect,insort,insort_left,insort_right

from math import gcd,ceil,floor,sqrt

from collections import Counter,defaultdict,deque,OrderedDict

from queue import Queue,PriorityQueue

from string import ascii_lowercase

sys.setrecursionlimit(10**6)
INF = float('inf')
MOD = 998244353
mod = 10**9+7

def isPrime(n):
    
    if (n <= 1) :return False
    if (n <= 3) :return True
    if (n%2 == 0 or n%3 == 0):return False
    for i in range(5,ceil(sqrt(n))+1,6):
        if (n%i==0 or n%(i+2)==0):
            return False
    return True


def st():
    return list(stdin.readline().strip())

def inp():
    return int(stdin.readline())

def li():
    return list(map(int,stdin.readline().split()))

def mp():
    return map(int,stdin.readline().split())

def pr(n):
    stdout.write(str(n)+"\n")
    
def DFS(dictionary,vertex,visited):
    visited[vertex]=True
    stack=[vertex]
    print(vertex)
    while stack:
        a=stack.pop()
        for i in dictionary[a]:
            if not visited[i]:
                print(i)
                visited[i]=True
                stack.append(i)


def BFS(dictionary, vertex,visited):
    visited[vertex]=True
    q=deque()
    q.append(vertex)
    while q:
        a=q.popleft()
        for i in dictionary[a]:
            if not visited[i]:
                visited[i]=True
                q.append(i)
                print(i)

                


def soe(limit):
    l=[1]*(limit+1)
    l[0]=0
    l[1]=0
    prime=[]
    for i in range(2,limit+1):
        if l[i]:
            for j in range(i*i,limit+1,i):
                l[j]=0
    
    for i in range(2,limit+1):
        if l[i]:
            prime.append(i)
    return prime

def segsoe(low,high):
    limit=int(high**0.5)+1
    prime=soe(limit)
    n=high-low+1
    l=[0]*(n+1)
    for i in range(len(prime)):
        lowlimit=(low//prime[i])*prime[i]
        if lowlimit<low:
            lowlimit+=prime[i]
        if lowlimit==prime[i]:
            lowlimit+=prime[i]
        for j in range(lowlimit,high+1,prime[i]):
            l[j-low]=1
    for i in range(low,high+1):
        if not l[i-low]:
            if i!=1:
                print(i)
                
def gcd(a,b):
    while b:
        a=a%b
        b,a=a,b
    return a

def power(a,n):
    r=1
    while n:
        if n&1:
            r=(r*a)
        a*=a
        n=n>>1
    return r
    
def solve():
    r,c,m=mp()
    row={}
    col={}
    dd={}
    d={}
    for i in range(m):
        l=li()
        a=l[0]
        b=l[1]
        row[a]=row.get(a,0)+1
        col[b]=col.get(b,0)+1
    
        if a in d:
            d[a].add(b)
        else:
            d[a]={b}

        if b in dd:
            dd[b].add(a)
        else:
            dd[b]={a}
    
    miR,miC=float('-inf'),float('-inf')
    
    for i in row:
        if row[i]>miR:
            miR=row[i]
            R=i
    for i in col:
        if col[i]>miC:
            miC=col[i]
            C=i

    ans=float('-inf')

    for i in col:
        c=miR+col[i]
        if i in d[R]:
            c-=1
        ans=max(ans,c)

    for  i in row:
        c=miC+row[i]
        if i in dd[C]:
            c-=1
        ans=max(ans,c)

    pr(ans)
        
        
        
            

for _ in range(1):
    solve()

Solution (Python):
h,w,m = map(int, input().split())
row = [0]*(h+1)
rn = [[] for _ in range(h+1)]
col = [0]*(w+1)
cn = [[] for _ in range(w+1)]
data = []
for _ in range(m):
  hd,wd = map(int, input().split())
  row[hd] += 1
  rn[hd].append(wd)
  col[wd] += 1
  cn[wd].append(hd)

cm = max(col)
rm = max(row)
ri = [x for x,y in enumerate(row) if y == rm]
ci = [x for x,y in enumerate(col) if y == cm]
for r in ri:
  rs = set(rn[r])
  for c in ci:
    if c not in rs:
      ans = cm+rm
      print(ans)
      exit()
ans = cm+rm-1
print(ans)

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

h_cnt = [0] * (H + 1)
w_cnt = [0] * (W + 1)

for h, w in hw:
    h_cnt[h] += 1
    w_cnt[w] += 1

h_mx = max(h_cnt)
w_mx = max(w_cnt)

cnt = h_cnt.count(h_mx) * w_cnt.count(w_mx)
for h, w in hw:
    val = h_cnt[h] + w_cnt[w]
    if val == h_mx + w_mx:
        cnt -= 1

if cnt:
    ans = h_mx + w_mx
else:
    ans = h_mx + w_mx - 1

print(ans)

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

def solve():
    H, W, M = map(int, input().split())
    numRs = [0] * H
    numCs = [0] * W
    hws = []
    for _ in range(M):
        h, w = map(int, input().split())
        h, w = h-1, w-1
        numRs[h] += 1
        numCs[w] += 1
        hws.append((h, w))

    maxR = max(numRs)
    maxC = max(numCs)

    hs = set()
    ws = set()
    for h in range(H):
        if numRs[h] == maxR:
            hs.add(h)
    for w in range(W):
        if numCs[w] == maxC:
            ws.add(w)
    numH = len(hs)
    numW = len(ws)

    num = 0
    for hb, wb in hws:
        if hb in hs and wb in ws:
            num += 1

    ans = maxR+maxC
    if num == numH*numW:
        ans -= 1

    print(ans)


solve()

Solution (Python):
h, w, m = map(int, input().split())
s = dict()
num_h = [0] * h
num_w = [0] * w
for _ in range(m):
    hi, wi = map(int, input().split())
    hi -= 1
    wi -= 1
    s[(hi, wi)] = True
    num_h[hi] += 1
    num_w[wi] += 1
max_h_list = []
max_h_val = 0
max_w_list = []
max_w_val = 0
for hi in range(h):
    if num_h[hi] > max_h_val:
        max_h_list = [hi]
        max_h_val = num_h[hi]
    elif num_h[hi] == max_h_val:
        max_h_list.append(hi)
for wi in range(w):
    if num_w[wi] > max_w_val:
        max_w_list = [wi]
        max_w_val = num_w[wi]
    elif num_w[wi] == max_w_val:
        max_w_list.append(wi)

if len(max_h_list) * len(max_w_list) > m:
    print(max_h_val + max_w_val)
    exit()
for max_hi in max_h_list:
    for max_wi in max_w_list:
        if s.get((max_hi, max_wi), False) == False:
            print(max_h_val + max_w_val)
            exit()
print(max_h_val + max_w_val - 1)

Solution (Python):
import sys
 
input = sys.stdin.readline
 
 
def main():
    H, W, M = map(int, input().split())
    row = [0] * (H)
    col = [0] * (W)
    bomb = set()
    for _ in range(M):
        h, w = map(int, input().split())
        bomb.add((h, w))
        row[h-1] += 1
        col[w-1] += 1
    row_max = max(row)
    row_index_list = [i for i, v in enumerate(row) if v == row_max]
    col_max = max(col)
    col_index_list = [i for i, v in enumerate(col) if v == col_max]
    ans = row_max + col_max - 1
    c = False
    for x in row_index_list:
        for y in col_index_list:
            if not (x + 1, y + 1) in bomb:
                c = True
                break
        if c:
            break
    if c:
        ans += 1
    print(ans)
 
 
if __name__ == '__main__':
    main()

Solution (Python):
import numpy as np

H, W, M = map(int, input().split())
h_t = [0]*H
w_t = [0]*W
t = {}
for i in range(M):
    h, w = map(int, input().split())
    t[(h-1, w-1)] = 1
    h_t[h-1]+=1
    w_t[w-1]+=1
h_max = max(h_t)
h_max_list = [i for i in range(len(h_t)) if h_t[i] == h_max]
w_max = max(w_t)
w_max_list = [i for i in range(len(w_t)) if w_t[i] == w_max]

for h in h_max_list:
    for w in w_max_list:
        if (h, w) not in t:
            print(h_max + w_max)
            exit()
print(h_max + w_max - 1)

Solution (Python):
from collections import deque

h,w,m = map(int,input().split())
Ms = []

h_scores = [0 for i in range(h)]
w_scores = [0 for i in range(w)]

record = set()

for i in range(m):
  h,w = map(int,input().split())
  record.add((h-1,w-1))
  h_scores[h-1] += 1
  w_scores[w-1] += 1

max_h = max(h_scores)
max_w = max(w_scores)
max_h_poss = [i for i,v in enumerate(h_scores) if v == max_h]
max_w_poss = [i for i,v in enumerate(w_scores) if v == max_w]

out_pos_count = 0 

c = False

for i in max_h_poss:
    for j in max_w_poss:
        if (i,j) not in record:
            c = True
            break        

if c:
    print(max(h_scores) + max(w_scores))
else:
    print(max(h_scores) + max(w_scores)-1)

Solution (Python):
H, W, M = map(int, input().split())
bom = set()
row = [0] * H
col = [0] * W

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

max_row = max(row)
max_col = max(col)
ans = max_row + max_col - 1

p, q = [], []

for i in range(H):
    if row[i] == max_row:
        p.append(i)

for j in range(W):
    if col[j] == max_col:
        q.append(j)

flag = False
for i in p:
    for j in q:
        if (i, j) not in bom:
            ans += 1
            flag = True
            break
    if flag:
        break

print(ans)

Solution (Python):
h, w, m = map(int, input().split())
h_cnt = [0] * h
w_cnt = [0] * w

bomb_set = set()

for i in range(m):
    h_, w_ = map(int, input().split())
    h_ -= 1
    w_ -= 1
    h_cnt[h_] += 1
    w_cnt[w_] += 1
    bomb_set.add((h_, w_))

max_h = max(h_cnt)
max_h_idx = []
for i in range(h):
    if h_cnt[i] == max_h:
        max_h_idx.append(i)

max_w = max(w_cnt)
max_w_idx = []
for i in range(w):
    if w_cnt[i] == max_w:
        max_w_idx.append(i)

minus = -1
for i in max_h_idx:
    for j in max_w_idx:
        if (i, j) not in bomb_set:
            print(max_h + max_w)
            exit()
print(max_h + max_w - 1)

Solution (Python):


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)

Solution (Python):

from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def S(): return input().rstrip()
def LS(): return S().split()
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float("INF")


def solve():
    h,w,m = LI()
    hw = LIR(m)
    
    
    dh = defaultdict(int)
    dh1 = defaultdict(int)
    dw = defaultdict(int)
    dw1 = defaultdict(int)
    ma = defaultdict(int)
    for hi, wi in hw:
        dh[hi] += 1
        dw[wi] += 1
        ma[(hi, wi)] = 1
    maxh = max(dh.values())
    maxw = max(dw.values())
    for key, value in dh.items():
        if value == maxh:
            dh1[key] = maxh
    for key, value in dw.items():
        if value == maxw:
            dw1[key] = maxw
    for kh, vh in dh1.items():
        for kw, vw in dw1.items():
            if ma[(kh, kw)] == 0:
                print(vh + vw)
                return
    print(vh + vw - 1)
    
    return



if __name__ == '__main__':
    solve()

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

h_count = {}
w_count = {}
for h,w in hw:
    if h in h_count:
        h_count[h] += 1
    else:
        h_count[h] = 1
    if w in w_count:
        w_count[w] += 1
    else:
        w_count[w] = 1

max_h = max(h_count.values())
max_w = max(w_count.values())
ans = max_h + max_w

max_h_list = set([k for k,v in h_count.items() if v == max_h])
max_w_list = set([k for k,v in w_count.items() if v == max_w])

num = 0
for h,w in hw:
    if h in max_h_list and w in max_w_list:
        num += 1

if num < len(max_h_list)*len(max_w_list):
    print(ans)
else:
    print(ans-1)

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

B = [list(map(int, input().split())) for _ in range(M)]

bombs_row = [0] * H
bombs_col = [0] * W

for b in B:
    bombs_row[b[0] - 1] += 1
    bombs_col[b[1] - 1] += 1

row_max = max(bombs_row)
col_max = max(bombs_col)

row_max_count = bombs_row.count(row_max)
col_max_count = bombs_col.count(col_max)

ans = row_max + col_max

possible_point = row_max_count * col_max_count

bombed_point = 0

for b in B:
    if bombs_row[b[0] - 1] == row_max and bombs_col[b[1] - 1] == col_max:
        bombed_point += 1

if bombed_point == possible_point:
    ans -= 1

print(ans)

Solution (Python):
import bisect, collections, copy, heapq, itertools, math, string, sys
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = float('inf')
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    H, W, M = LI()
    hw = {tuple(LI()) for _ in range(M)}

    cnt_h = collections.Counter([h for h, w in hw])
    cnt_w = collections.Counter([w for h, w in hw])

    max_h = max(cnt_h.values())
    max_w = max(cnt_w.values())
    max_h_k = [k for k, v in cnt_h.items() if v == max_h]
    max_w_k = [k for k, v in cnt_w.items() if v == max_w]

    
    
    is_on_target = True
    for i, j in itertools.product(max_h_k, max_w_k):
        if (i, j) not in hw:
            is_on_target = False
            break

    if is_on_target:
        ans = max_h + max_w - 1
    else:
        ans = max_h + max_w
    print(ans)

if __name__ == '__main__':
    resolve()

Solution (Python):



import collections
import sys
import copy
import re
import math
import itertools


def I(): return int(sys.stdin.readline().rstrip())
def LI(): return list(map(int, sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())


def main():
    H, W, M = LI()

    HList = [0]*H
    WList = [0]*W
    graph = set()
    for m in range(M):
        h, w = LI()
        HList[h-1] += 1
        WList[w-1] += 1
        graph.add((h-1, w-1))

    Hmax = max(HList)
    Wmax = max(WList)

    HIndex = [i for i, v in enumerate(HList) if v == Hmax]
    WIndex = [i for i, v in enumerate(WList) if v == Wmax]

    ans = Hmax + Wmax
    for h in HIndex:
        for w in WIndex:
            if not (h, w) in graph:
                print(ans)
                return

    print(ans-1)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import defaultdict
H, W, M = map(int, input().split())
rows = {i: 0 for i in range(H)}
cols = {i: 0 for i in range(W)}
d = defaultdict(int)
for _ in range(M):
    h, w = map(int, input().split())
    h -= 1
    w -= 1
    rows[h] += 1
    cols[w] += 1
    d[(h,w)] += 1
mr = max(rows.values())
mc = max(cols.values())
max_rows = [kv for kv in rows.items() if kv[1] == mr]
max_cols = [kv for kv in cols.items() if kv[1] == mc]
non_dup = False
ans = max_rows[0][1] + max_cols[0][1]
flg = False
for kh, vh in max_rows:
    for kw, vw in max_cols:
        if d[(kh, kw)] == 0:
            non_dup = True
            flg = True
            break
    if flg:
        break
if not non_dup:
    ans -= 1
print(ans)

Solution (Python):
import sys,bisect

from sys  import stdin,stdout

from bisect import bisect_left,bisect_right,bisect,insort,insort_left,insort_right

from math import gcd,ceil,floor,sqrt

from collections import Counter,defaultdict,deque,OrderedDict

from queue import Queue,PriorityQueue

from string import ascii_lowercase

sys.setrecursionlimit(10**6)
INF = float('inf')
MOD = 998244353
mod = 10**9+7

def isPrime(n):
    
    if (n <= 1) :return False
    if (n <= 3) :return True
    if (n%2 == 0 or n%3 == 0):return False
    for i in range(5,ceil(sqrt(n))+1,6):
        if (n%i==0 or n%(i+2)==0):
            return False
    return True


def st():
    return list(stdin.readline().strip())

def inp():
    return int(stdin.readline())

def li():
    return list(map(int,stdin.readline().split()))

def mp():
    return map(int,stdin.readline().split())

def pr(n):
    stdout.write(str(n)+"\n")
    
def DFS(dictionary,vertex,visited):
    visited[vertex]=True
    stack=[vertex]
    print(vertex)
    while stack:
        a=stack.pop()
        for i in dictionary[a]:
            if not visited[i]:
                print(i)
                visited[i]=True
                stack.append(i)


def BFS(dictionary, vertex,visited):
    visited[vertex]=True
    q=deque()
    q.append(vertex)
    while q:
        a=q.popleft()
        for i in dictionary[a]:
            if not visited[i]:
                visited[i]=True
                q.append(i)
                print(i)

                


def soe(limit):
    l=[1]*(limit+1)
    l[0]=0
    l[1]=0
    prime=[]
    for i in range(2,limit+1):
        if l[i]:
            for j in range(i*i,limit+1,i):
                l[j]=0
    
    for i in range(2,limit+1):
        if l[i]:
            prime.append(i)
    return prime

def segsoe(low,high):
    limit=int(high**0.5)+1
    prime=soe(limit)
    n=high-low+1
    l=[0]*(n+1)
    for i in range(len(prime)):
        lowlimit=(low//prime[i])*prime[i]
        if lowlimit<low:
            lowlimit+=prime[i]
        if lowlimit==prime[i]:
            lowlimit+=prime[i]
        for j in range(lowlimit,high+1,prime[i]):
            l[j-low]=1
    for i in range(low,high+1):
        if not l[i-low]:
            if i!=1:
                print(i)
                
def gcd(a,b):
    while b:
        a=a%b
        b,a=a,b
    return a

def power(a,n):
    r=1
    while n:
        if n&1:
            r=(r*a)
        a*=a
        n=n>>1
    return r
    
def solve():
    r,c,m=mp()
    row={}
    col={}
    dd={}
    d={}
    for i in range(m):
        l=li()
        a=l[0]
        b=l[1]
        row[a]=row.get(a,0)+1
        col[b]=col.get(b,0)+1
    
        if a in d:
            d[a].add(b)
        else:
            d[a]={b}

        if b in dd:
            dd[b].add(a)
        else:
            dd[b]={a}
    
    miR,miC=float('-inf'),float('-inf')
    
    for i in row:
        if row[i]>miR:
            miR=row[i]
            R=i
    for i in col:
        if col[i]>miC:
            miC=col[i]
            C=i

    ans=float('-inf')

    for i in col:
        c=miR+col[i]
        if i in d[R]:
            c-=1
        ans=max(ans,c)

    for  i in row:
        c=miC+row[i]
        if i in dd[C]:
            c-=1
        ans=max(ans,c)

    pr(ans)
        
        
        
            

for _ in range(1):
    solve()

Solution (Python):
h,w,m = list(map(int,input().split()))
t = [list(map(int,input().split())) for _ in range(m)]
from collections import Counter
 
x,y = zip(*t)

xcnt = Counter(x)
ycnt = Counter(y)
 
xcmax = max( xcnt.values() )
ycmax = max( ycnt.values() )
xlist = [k for k,v in xcnt.items() if v == xcmax]
ylist = [k for k,v in ycnt.items() if v == ycmax]
if len(xlist) * len(ylist) > m:
  print( xcmax + ycmax )
else:
  xylist = { i*(10**6)+j for i in xlist for j in ylist }
  tlist = { i[0]*(10**6) + i[1] for i in t }
  if len( xylist - tlist ) == 0:
    print( xcmax + ycmax -1 )
  else:
    print( xcmax + ycmax )

Solution (Python):





def int_mtx(N):
    x = []
    for _ in range(N):
        x.append(list(map(int,input().split())))
    return x

def str_mtx(N):
    x = []
    for _ in range(N):
        x.append(list(input()))
    return x

def int_map():
    return map(int,input().split())

def int_list():
    return list(map(int,input().split()))

def print_space(l):
    return print(" ".join([str(x) for x in l]))


import numpy as np
import statistics
import math
import collections


H,W,M = int_map()
hw = int_mtx(M)

h = []
w = []
for hhww in hw:
    h.append(hhww[0])
    w.append(hhww[1])

ch = collections.Counter(h)
cw = collections.Counter(w)
a = ch.most_common()[0][1]
b = cw.most_common()[0][1]

if a == M or b == M:
    print(M)
    exit()

if a < b:
    bb = cw.most_common()[0][0]
    hw1 = [i for i in hw if not i[1] == bb]
    
    h1 = []
    for hhww in hw1:
        h1.append(hhww[0])

    ch1 = collections.Counter(h1)
    a1 = ch1.most_common()[0][1]

    print(b+a1)
    exit()
else:
    aa = ch.most_common()[0][0]
    hw1 = [i for i in hw if not i[0] == aa]
    
    w1 = []
    for hhww in hw1:
        w1.append(hhww[1])

    cw1 = collections.Counter(w1)
    b1 = cw1.most_common()[0][1]

    print(a+b1)
    exit()

Solution (Python):
H,W,M = map(int,input().split())
T = [0] * M
H_cnt = {}
W_cnt = {}
HW = {}
for i in range(M):
    h,w = map(int,input().split())
    if not h in H_cnt:
        H_cnt[h] = 0
    if not w in W_cnt:
        W_cnt[w] = 0
    H_cnt[h] += 1
    W_cnt[w] += 1
    HW[(h,w)] = 1

HL = [[h,cnt] for h,cnt in H_cnt.items()]
WL = [[w,cnt] for w,cnt in W_cnt.items()]

HL.sort(key=lambda x: x[1],reverse=True)
WL.sort(key=lambda x: x[1],reverse=True)

HS = {}
max_cnth = 0
for h,cnt in HL:
    if max_cnth<=cnt:
        HS[h] = cnt
        max_cnth = max(max_cnth,cnt)
        continue
    break

WS = {}
max_cntw = 0
for w,cnt in WL:
    if max_cntw<=cnt:
        WS[w] = cnt
        max_cntw = max(max_cntw,cnt)
        continue
    break

cnt = 0
ans = 0


cross_cnt = 0
for hw in HW.keys():
    h,w = hw
    if h in HS and w in WS:
        cross_cnt+=1
if len(WS) * len(HS)==cross_cnt:
    print(max_cnth+max_cntw-1)
    exit()
print(max_cnth+max_cntw)

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

lh = []
lw = []

for i in range(m):
  h1,w1 = map(int, input().split())
  lh.append(h1)
  lw.append(w1)

if h == 1 or w == 1:
  print(m)
else:
  from collections import Counter as co
  ch=co(lh).most_common()
  cw=co(lw).most_common()
  
  ans = 0
  tmp = ch[0][0]
  lh_c = [i for i, x in enumerate(lh) if x == tmp]
  lw_tmp = lw[:]
  for j in sorted(lh_c, reverse=True):
    lw_tmp.pop(j)
  if len(lw_tmp) == 0:
    print(ch[0][1])
  else:
    cw_tmp = co(lw_tmp).most_common()
    ans = ch[0][1]+cw_tmp[0][1]
    
    tmp = cw[0][0]
    lw_c = [i for i, x in enumerate(lw) if x == tmp]
    lh_tmp = lh[:]
    for j in sorted(lw_c, reverse=True):
      lh_tmp.pop(j)
    if len(lh_tmp) == 0:
      print(cw[0][1])
    else:
      ch_tmp = co(lh_tmp).most_common()
      ans = max(ans, cw[0][1]+ch_tmp[0][1])
      print(ans)