Harryxun/sft_time huggingface dataset:
### BUGGY CODE ###

# from collections import Counter
N = int(input())
s = [''.join(sorted(input())) for _ in range(N)]

# sN = [input() for _ in range(N)]
# # counts = [Counter(s) for s in sN]
# # pool = []
# # ans = 0
# # for count in counts:
# #     if count in pool:
# #         ans += 1
# #     else:
# #         pool.append(count)
# # print(pool)
# # # print(get_unique_list(counts))
ans = 0
for i in range(N-1):
    for j in range(i+1, N):
        if sorted(s[i]) == sorted(s[j]):
            ans += 1
print(ans)

### FIXED CODE ###

from collections import Counter
from scipy.misc import comb
N = int(input())
s = [''.join(sorted(input())) for _ in range(N)]
ans = 0
for count in Counter(s).values():
    ans += comb(count, 2, exact=True)
print(ans)
### BUGGY CODE ###

N, M = map(int, input().split())

A = list(map(int, input().split()))

for i in range(M):
    maxA = max(A)
    A.remove(maxA)
    maxA = maxA // 2
    A.append(maxA)

print(sum(A))

### FIXED CODE ###

import heapq
N, M = map(int, input().split())

A = list(map(int, input().split()))
h = []

for i in range(N):
    A[i] *= -1

for i in range(N):
    heapq.heappush(h, A[i])

for i in range(M):
    num = heapq.heappop(h)
    num = num * -1
    num = num // 2
    heapq.heappush(h, -num)

print(-sum(h))
### BUGGY CODE ###

n = int(input())
ans = 0
for i in range(n):
    ans += i
print(ans)

### FIXED CODE ###

n = int(input())
print(int((n-1) * n // 2))
### BUGGY CODE ###

n = int(input())
x = input()
a = x.count('1')
b = int(x,2)
# print (b)

ary = [None for i in range(200010)]
ary[0] = 0

def f(n):
  if ary[n] is not None:
    return ary[n]
  b = bin(n).count('1')
  r = 1 + f(n%b)
  ary[n] = r
  return ary[n]


a1 = a + 1
a0 = a - 1
for i in range(200010):
  f(i)


one = [1] * 200010
zero = [1] * 200010
for i in range(1, 200010):
    if a0 != 0:
        one[i] = one[i-1] * 2 % a0
    zero[i] = zero[i-1] * 2 % a1


ans = [0 for i in range(n)]
for i in range(n-1, -1, -1):
  if x[n-1-i] == '0':
    y = b + zero[i]
    # y = x %a1
    y %= a1
    print (ary[y]+1)
  else:
    if a0 != 0:
      y = b - one[i]
      # y = x %a0
      y %= a0
      print (ary[y]+1)
    else:
      print (0)
# ans.reverse()
# for i in ans:
#   print (i)

### FIXED CODE ###

n = int(input())
x = input()
a = x.count('1')
b = int(x,2)
# print (b)

ary = [None for i in range(200010)]
ary[0] = 0

def f(n):
  if ary[n] is not None:
    return ary[n]
  b = bin(n).count('1')
  r = 1 + f(n%b)
  ary[n] = r
  return ary[n]


a1 = a + 1
a0 = a - 1
for i in range(200010):
  f(i)


one = [1] * 200010
zero = [1] * 200010
for i in range(1, 200010):
    if a0 != 0:
        one[i] = one[i-1] * 2 % a0
    zero[i] = zero[i-1] * 2 % a1


ans = [0 for i in range(n)]
c1 = b%a1
if a0 != 0:
  c0 = b%a0
for i in range(n-1, -1, -1):
  if x[n-1-i] == '0':
    y = c1 + zero[i]
    # y = x %a1
    y %= a1
    print (ary[y]+1)
  else:
    if a0 != 0:
      y = c0 - one[i]
      y %= a0
      print (ary[y]+1)
    else:
      print (0)
# ans.reverse()
# for i in ans:
#   print (i)
### BUGGY CODE ###

S = input()
cnt = 0
for i in range(len(S)):
    for j in range(1, len(S)+1):
        if i >= j:
            continue
        if int(S[i:j]) % 2019 == 0:
            cnt += 1
print(cnt)


### FIXED CODE ###

S = input()
mod_bucket = [0] * 2019
mod_bucket[0] += 1

_S = S[::-1]
mod = 0
p = 1
for i in range(len(S)):
    mod = (p * int(_S[i]) + mod) % 2019
    mod_bucket[mod] += 1
    p *= 10
    p %= 2019

ans = sum([mod*(mod-1)/2 for mod in mod_bucket])
print(int(ans))
### BUGGY CODE ###

from operator import add, mul, sub, or_


class SegmentTree:
    '''
    セグメント木(遅延ではない)
    1-indexd セグメント木
    values : 値の配列
    op : 区間に対する関数
    ie : 初期値
    '''

    def __init__(self, values, op, ie):
        self.values = values
        vlen = len(values)
        self.op = op
        self.size = 2 ** (vlen-1).bit_length()
        self.tree = [ie]*self.size + self.values + [ie]*(self.size-vlen)
        self.ie = ie

        for i in range(self.size-1, 0, -1):
            self.tree[i] = self.op(self.tree[i*2], self.tree[i*2+1])

    def update(self, i, v):
        i += self.size
        self.tree[i] = v
        while i > 0:
            i //= 2
            self.tree[i] = self.op(self.tree[i*2], self.tree[i*2+1])

    def query(self, l, r):
        l += self.size
        r += self.size
        ret = self.ie
        while l < r:
            if l & 1:
                ret = self.op(ret, self.tree[l])
                l += 1
            if r & 1:
                r -= 1
                ret = self.op(ret, self.tree[r])
            l //= 2
            r //= 2
        return ret


N, Q = map(int, input().split())
*c, = map(int, input().split())

q = [[] for _ in range(N+1)]
for i in range(Q):
    x, y = map(int, input().split())
    q[y-1].append([i, x-1])

st = SegmentTree([0]*(N+1), add, 0)
finds = [-1]*(N+1)
ans = [0]*Q
for i in range(N):
    if finds[c[i]] != -1:
        st.update(finds[c[i]], 0)

    finds[c[i]] = i
    st.update(finds[c[i]], 1)

    for j, x in q[i]:
        ans[j] = st.query(x, i+1)

for a in ans:
    print(a)


### FIXED CODE ###

from operator import add, mul, sub, or_


class SegmentTree:
    '''
    セグメント木(遅延ではない)
    1-indexd セグメント木
    values : 値の配列
    op : 区間に対する関数
    ie : 初期値
    '''

    def __init__(self, values):
        self.values = values
        vlen = len(values)
        self.size = 2 ** (vlen-1).bit_length()
        self.tree = [0]*self.size + self.values + [0]*(self.size-vlen)

        for i in range(self.size-1, 0, -1):
            self.tree[i] = self.tree[i*2] + self.tree[i*2+1]

    def update(self, i, v):
        i += self.size
        self.tree[i] = v
        while i > 0:
            i //= 2
            self.tree[i] = self.tree[i*2] + self.tree[i*2+1]

    def query(self, l, r):
        l += self.size
        r += self.size
        ret = 0
        while l < r:
            if l & 1:
                ret += self.tree[l]
                l += 1
            if r & 1:
                r -= 1
                ret += self.tree[r]
            l //= 2
            r //= 2
        return ret


N, Q = map(int, input().split())
*c, = map(int, input().split())

q = [[] for _ in range(N+1)]
for i in range(Q):
    x, y = map(int, input().split())
    q[y-1].append([i, x-1])

st = SegmentTree([0]*(N+1))
finds = [-1]*(N+1)
ans = [0]*Q
for i in range(N):
    if finds[c[i]] != -1:
        st.update(finds[c[i]], 0)

    finds[c[i]] = i
    st.update(finds[c[i]], 1)

    for j, x in q[i]:
        ans[j] = st.query(x, i+1)

for a in ans:
    print(a)
### BUGGY CODE ###

N, M = list(map(int, input().rstrip().split()))

st = []
tt = []

for i in range(M):
    s, t = list(map(int, input().rstrip().split()))
    if s == 1:
        st.append(t)
    
    if t == N:
        tt.append(s)

st.sort()
tt.sort()
result = 'IMPOSSIBLE'
for s in st:
    if s in tt:
        result = 'POSSIBLE'
        break


print(result)
        


### FIXED CODE ###

N, M = list(map(int, input().rstrip().split()))

st = []
dic = {}

for i in range(M):
    s, t = list(map(int, input().rstrip().split()))
    if s == 1:
        st.append(t)
    
    if t == N:
        dic[s] = 0

result = 'IMPOSSIBLE'
for s in st:
    if s in dic:
        result = 'POSSIBLE'
        break


print(result)
### BUGGY CODE ###

import numpy as np
import itertools

k,s = map(int, input().split())
l = np.arange(k+1)
ans = 0

p = np.array(list(itertools.combinations_with_replacement(l,3)))
p = p[np.sum(p,axis=1)==s]
p = np.array([np.unique(row).size for row in p])

print(np.count_nonzero(p==1)+np.count_nonzero(p==2)*3+np.count_nonzero(p==3)*6)


### FIXED CODE ###

k,s = map(int, input().split())
ans = 0

for x in range(k+1):
  for y in range(k+1):
    if 0<=s-x-y and s-x-y <=k:
      ans+=1
print(ans)
### BUGGY CODE ###

a,b,n = map(int,input().split())


x = 2

def hantei(x,a,b):
    rr = 0
    rr = int(a*x//b) - a * int(x//b)
    return rr



mx = n//b
ans = 0
ans_n = hantei(n,a,b)
ans_0 = hantei(0,a,b)

if(mx == 0):
    x = n
    ans = hantei(x,a,b)
else:
    flag = 1
    for i in range(1,mx+1):
        x = i*b - 1
        ans = max(ans,hantei(x,a,b))

asn = max(ans,ans_n,ans_0)    
print(ans)
        
    


### FIXED CODE ###

a,b,n = map(int,input().split())


x = 2

def hantei(x,a,b):
    rr = 0
    rr = int(a*x//b) - a * int(x//b)
    return rr



mx = n//b
ans = 0
ans_n = hantei(n,a,b)
ans_0 = hantei(0,a,b)

if(mx == 0):
    x = n
    ans = hantei(x,a,b)
else:
    flag = 1
    x = 2*b - 1
    ans = max(ans,hantei(x,a,b))
    #print(ans)

asn = max(ans,ans_n,ans_0)    
print(ans)
### BUGGY CODE ###

def nyu():
    N, M = map(int, input().split())
    X = list(map(int,input().split()))
    X.sort()
    return N,M,X


def kansu(N,M,X):

    x_abs = [X[m+1] -X[m] for m in range(M-1)]    
#    print(x_abs)
    cnt_n = N
    
    while cnt_n-1 > 0:
        x_abs[x_abs.index(max(x_abs))]  = 0
        cnt_n -= 1

    koma_max = 0
    for m in range(M-1):
        koma_max += x_abs[m]

    print(koma_max)


N,M,X = nyu()
#print(X)

if M == 1:
    print(0)
else:
    kansu(N,M,X)

#print(S)



### FIXED CODE ###

def nyu():
    N, M = map(int, input().split())
    X = list(map(int,input().split()))
    X.sort()
    return N,M,X


def kansu(N,M,X):

    x_abs = [X[m+1] -X[m] for m in range(M-1)]    
#    print(x_abs)

    
    x_abs.sort()

    koma_max = 0
    for m in range(M-N):
        koma_max += x_abs[m]

    print(koma_max)


N,M,X = nyu()
#print(X)

if M == 1:
    print(0)
else:
    kansu(N,M,X)

#print(S)
### BUGGY CODE ###

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


n,m=map(int,input().split())
uf=UnionFind(n)
for _ in range(m):
  a,b=map(int,input().split())
  uf.union(a-1,b-1)

dic=uf.all_group_members()
max_size=0
for ss in dic.values():
  max_size=max(max_size,len(ss))

print(max_size)

### FIXED CODE ###

n,m=map(int,input().split())
par = [-1]*(n+1)
def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x]) #経路圧縮
        return par[x]
def same(x,y):
    return find(x) == find(y)
def unite(x,y):
    x = find(x)
    y = find(y)
    if x == y:
      return 0
    else:
      if par[x] > par[y]:
        x,y = y,x
      par[x] += par[y]
      par[y] = x
def size(x):
    return -par[find(x)]

max_size=0
for _ in range(m):
  a,b=map(int,input().split())
  unite(a,b)
  
print(-min(par))
### BUGGY CODE ###

K = int(input())
A = 7 % K 
if K % 2 == 0:
    print(-1)
    exit()
for i in range(1, K + 1):
    if A % K == 0:
        print(i)
        break
    A = 10 * A + 7


### FIXED CODE ###

K = int(input())
ans = -1
N = 7
for i in range(K):
    if N % K == 0:
        ans = i+1
        break
    N = (N*10+7) % K
print(ans)
### BUGGY CODE ###

N = int(input())
A = list(map(int, input().split()))
count=0


def merge(A, left, mid, right):
    global count
    n1 = mid - left
    n2 = right - mid
    L = []
    R = []
    for i in range(n1):
        L.append(A[left + i])
    for i in range(n2):
        R.append(A[mid + i])

    L.append(float("inf"))
    R.append(float("inf"))
    i, j = 0, 0
    for k in range(left, right):
        if L[i] <= R[j]:
            A[k] = L[i]
            i += 1
        else:
            A[k] = R[j]
            j += 1
    count += right - left


def mergeSort(A, left, right):
    if left+1 < right:
        mid = (left + right)//2
        mergeSort(A, left, mid)
        mergeSort(A, mid, right)
        merge(A, left, mid, right)

mergeSort(A,0,N)


print(" ".join(map(str,A)))
print(count)

### FIXED CODE ###

def merge(a, left, mid, right):
    global count
    n1 = mid - left
    n2 = right - mid
    L = a[left:left + n1] + [SENTINEL]
    R = a[mid:mid + n2] + [SENTINEL]
    i = j = 0
    for k in range(left, right):
        if L[i] <= R[j]:
            a[k] = L[i]
            i += 1
        else:
            a[k] = R[j]
            j += 1
    count += right - left
 
def merge_sort(a, left, right):
    if left + 1 < right:
        mid = (left + right) // 2
        merge_sort(a, left, mid)
        merge_sort(a, mid, right)
        merge(a, left, mid, right)
 
SENTINEL = 1000000001
n = int(input())
a = list(map(int, input().strip().split()))
count = 0
merge_sort(a, 0, len(a))
print(' '.join(map(str, a)))
print(count)
### BUGGY CODE ###

N = int(input())

L = list(list(map(int,input().split())) for i in range(N))
#print(L)
#turn = "taka"
takapoint = 0
aokipoint = 0

L = sorted(L,key=lambda x: x[1],reverse=True)
L = sorted(L,key=lambda x: x[0],reverse=True)

for i in range(N) :
#while len(L) :
    if not i % 2 :
        L = sorted(L,key=lambda x: x[0],reverse=True)
        takapoint += L[0][0]
        L.pop(0)
        #turn = "aoki"
    else :
        L = sorted(L,key=lambda x: x[1],reverse=True)
        aokipoint += L[0][1]
        L.pop(0)
        #turn = "taka"
ans = takapoint - aokipoint

print(ans)


### FIXED CODE ###

N = int(input())
L = []
ans = 0
for i in range(N) :
    a,b = map(int,input().split())
    L.append([a,b,a+b])
L = sorted(L,key=lambda x:x[2],reverse=True)
takapoint = 0
aokipoint = 0
for i in range(N) :
    if i % 2 == 0 :
        takapoint += L[i][0]
    else :
        aokipoint += L[i][1]
ans = takapoint - aokipoint
print(ans)
### BUGGY CODE ###

X=int(input())
for B in range(-10**7,10**7):
    if type((X+B**5)**0.2)!=complex:
        if (X+B**5)**0.2==int((X+B**5)**0.2):
            print(int((X+B**5)**0.2), B)
            break

### FIXED CODE ###

X=int(input())
for B in range(-10**3,10**3):
    if type((X+B**5)**0.2)!=complex:
        if int((X+B**5)**0.2)-0.0001<=(X+B**5)**0.2<=int((X+B**5)**0.2)+0.0001:
            print(int((X+B**5)**0.2), B)
            break
### BUGGY CODE ###

import numpy as np

def is_prime(a):
  if a == 1:
    return False
  
  for i in range(2, 1+int(a**0.5)):
    if a % i == 0:
      return False
  return True

n = int(input())

ans = 0
z = 2
while True:
  if z > n:
    break
  if is_prime(n):
    ans += 1
    break
    
  if n % z != 0:
    z += 1
    continue
  for p in range(2, z+1):
    if not is_prime(p):
      continue
    tmp = np.log(z)/np.log(p)
    if tmp > 0 and tmp == int(tmp):
      n = n/z
      ans += 1
      z += 1
      break
  else:
    z += 1

print(ans)

### FIXED CODE ###

import numpy as np

def is_prime(a):
  if a == 1:
    return False
  
  for i in range(2, 1+int(a**0.5)):
    if a % i == 0:
      return False
  return True

def make_divisors(n):
    lower_divisors , upper_divisors = [], []
    i = 1
    while i*i <= n:
        if n % i == 0:
            lower_divisors.append(i)
            if i != n // i:
                upper_divisors.append(n//i)
        i += 1
    return lower_divisors + upper_divisors[::-1]

n = int(input())

ans = 0
divisors = make_divisors(n)
for d in divisors[1:]:
  if d > n:
    break
  if is_prime(n):
    ans += 1
    break
    
  tmp_divisors = make_divisors(d)
  for p in tmp_divisors[1:]:
    if not is_prime(p):
      continue
    tmp = np.log(d)/np.log(p)
    if tmp > 0 and tmp == int(tmp) and n % d == 0:
      n = n/d
      ans += 1
      break

print(ans)
### BUGGY CODE ###

import sys
sys.setrecursionlimit(10 ** 7)
read = sys.stdin.buffer.read 
inp = sys.stdin.buffer.readline
def inpS(): return inp().rstrip().decode()

def resolve():
    MOD = 10 ** 9 + 7
    def COMinit(n, MOD):
        fact = [1, 1]
        fact_inv = [1, 1]
        inv = [0, 1]
        for i in range(2, n + 1):
            fact.append((fact[-1] * i) % MOD)
            inv.append((-inv[MOD % i] * (MOD // i)) % MOD)
            fact_inv.append((fact_inv[-1] * inv[i]) % MOD)
        return fact, fact_inv

    # 二項係数計算
    def Combination(n, k, MOD=10 ** 9 + 7):
        # fac, finv = COMinit(n, MOD)
        if n < k: return 0
        if n < 0 or k < 0: return 0
        ret = fac[n] * (finv[k] * finv[n - k] % MOD) % MOD
        return ret

    K = int(inp())
    S = inpS()
    N = len(S)

    fac, finv = COMinit(N + K, MOD)
    v = 1
    ans = 0
    for i in range(K + 1):
        ans += Combination(N + K, i) * v
        ans %= MOD
        v *= 25
        v %= MOD
    print(ans)

if __name__ == "__main__":
    resolve()

### FIXED CODE ###

def resolve():
    MOD = 10 ** 9 + 7
    def COMinit(n, MOD):
        fact = [1, 1]
        fact_inv = [1, 1]
        inv = [0, 1]
        for i in range(2, n + 1):
            fact.append((fact[-1] * i) % MOD)
            inv.append((-inv[MOD % i] * (MOD // i)) % MOD)
            fact_inv.append((fact_inv[-1] * inv[i]) % MOD)
        return fact, fact_inv
 
    # 二項係数計算
    def Combination(n, k, MOD=10 ** 9 + 7):
        # fac, finv = COMinit(n, MOD)
        if n < k: return 0
        if n < 0 or k < 0: return 0
        ret = fac[n] * (finv[k] * finv[n - k] % MOD) % MOD
        return ret
 
    K = int(input())
    S = input()
    N = len(S)
 
    fac, finv = COMinit(N + K, MOD)
    v = 1
    ans = 0
    for i in range(K + 1):
        ans += Combination(N + K, i) * v
        ans %= MOD
        v *= 25
        v %= MOD
    print(ans)
    
if __name__ == "__main__":
    resolve()
### BUGGY CODE ###

n,m=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
import bisect
mod=10**9+7
a.sort()
b.sort()
ans=1
flag=True
if len(set(a))!=n or len(set(b))!=m:
    flag=False
    print(0)
def find(X,lists):
    return bisect.bisect_right(lists,X)!=bisect.bisect_left(lists,X)
    
if flag:
    for i in range(n*m,0,-1):
        #n*m-i+1番目の値をたす.
        if find(i,a):
            if find(i,b):
                pass    
            else:
                ans*=(m-bisect.bisect_left(b,i))
                ans=ans%mod
            
        else:
            if find(i,b):
                ans*=(n-bisect.bisect_right(a,i))
                ans=ans%mod
                
            else:
                ans*=((n-bisect.bisect_left(a,i))*(m-bisect.bisect_left(b,i))-(n*m-i))
                ans=ans%mod
    print(ans)             



### FIXED CODE ###

n,m=map(int,input().split())
a=list(map(int,input().split()))
b=list(map(int,input().split()))
import bisect
mod=10**9+7
a.sort()
b.sort()
ans=1
flag=True
if len(set(a))!=n or len(set(b))!=m:
    flag=False
    print(0)
def find(X,lists):
    return bisect.bisect_right(lists,X)!=bisect.bisect_left(lists,X)
    
if flag:
    for i in range(n*m,0,-1):
        #n*m-i+1番目の値をたす.
        if find(i,a):
            if find(i,b):
                pass    
            else:
                ans*=(m-bisect.bisect_left(b,i))
                ans=ans%mod
            
        else:
            if find(i,b):
                ans*=(n-bisect.bisect_right(a,i))
                ans=ans%mod
                
            else:
                ans*=((n-bisect.bisect_left(a,i))*(m-bisect.bisect_left(b,i))-(n*m-i))
                ans=ans%mod
    print(ans)
### BUGGY CODE ###

import sys
N,K,Q =map(int,input().split())
F = {}
A = []
for l in sys.stdin:
    A.append(int(l))
for i in range(N):
    cnt = A.count(i+1)
    F[str('A'+ str(i+1))] = K - (Q - cnt)
    if F[str('A'+ str(i+1))] >= 1 :
        print("Yes")
    else:
        print("No")

### FIXED CODE ###

N,K,Q=map(int,input().split())
L=[K]*N
for i in range(Q):
    A=int(input())
    L[A-1] += 1

for i in L:
    if i - Q > 0 :
        print("Yes")
    else :
        print("No")
### BUGGY CODE ###

n = int(input())
p = list(map(int, input().split()))
#print(p)

ans = 0

#for i in range(1, n+1):
#    cnt = 0
#    for j in (1, i):
#        if p[i] <= p[j]:
#            cnt += 1
#            print(cnt)
#    if cnt == i:
#        ans += 1

for i in range(n):
    #q = p[0:i+1]
    #print(q)
    if p[i] <= min(p[0:i+1]):
        ans += 1

print(ans)

### FIXED CODE ###

N = int(input())
P = [int(x) for x in input().split()]
cnt=1
tmp=P[0]
for i in range(1, N):
    tmp = min(tmp, P[i-1])
    if tmp >= P[i]:
        cnt+=1
#         print(i, cnt)
        
print(cnt)
### BUGGY CODE ###

from itertools import combinations

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

min_diff = 10**9
max_diff = 1
min_sum = 2 * 10**9
max_sum = 2

for x,y in XY:
    min_diff = min(x-y, min_diff)
    max_diff = max(x-y, max_diff)
    min_sum = min(x+y, min_sum)
    max_sum = max(x+y, max_sum)

cand_set = set()
for x,y in XY:
    if x-y in (min_diff, max_diff) or x+y in (min_sum, max_sum):
        cand_set.add((x, y))

dist = 0
for p1, p2 in combinations(cand_set, 2):
    dist = max(dist, abs(p1[0]-p2[0]) + abs(p1[1]-p2[1]))
    
print(dist)

### FIXED CODE ###

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

min_diff = 10**9
max_diff = -10**9
min_sum = 2 * 10**9
max_sum = 2

for x,y in XY:
    min_diff = min(x-y, min_diff)
    max_diff = max(x-y, max_diff)
    min_sum = min(x+y, min_sum)
    max_sum = max(x+y, max_sum)

print(max(max_sum-min_sum, max_diff-min_diff))
### BUGGY CODE ###

import math
from functools import reduce
def gcd(*number):
    return reduce(math.gcd, number)
n = int(input())
a, b, c = 1, 1, 1
sum = 0
list_number = []
while True:
    list_number.append(gcd(a, b, c))
    if n > c:
        c += 1
    elif n == c and n == b and n == a:
        break
    elif n == c and n == b:
        a += 1
        b = 1
        c = 1
    elif n == c:
        b += 1
        c = 1
for i in list_number:
    sum = sum + i
print(sum)

### FIXED CODE ###

from math import gcd
n = int(input())
sum = 0
for i in range(1, n+1):
    for j in range(1, n+1):
        for k in range(1, n+1):
            sum += gcd(gcd(i, j), k)
print(sum)
### BUGGY CODE ###

h,w,m=map(int,input().split())
bomb=[list(map(int, input().split())) for _ in range(m)]
res1=[0 for _ in range(h)]
res2=[0 for _ in range(w)]
for i in range(m):
    res1[bomb[i][0]-1]+=1
    res2[bomb[i][1]-1]+=1
ans1=max(res1)
ans2=max(res2)
ans=ans1+ans2
s1=0
l1=[]
for j in range(h):
    if res1[j]>s1:
            l1=[j+1]
            s1=res1[j]
    elif res1[j]==s1:
            l1.append(j+1)
s2=0
l2=[]
for k in range(w):
    if res2[k]>s2:
            l2=[k+1]
            s2=res2[k]
    elif res2[k]==s2:
            l2.append(k+1)
count=0
for l in range(m):
    bomb1=bomb[l]
    if bomb1[0] in l1 and bomb1[1] in l2:
        count+=1

if count!=len(l1)*len(l2):
    print(ans)
else:
    print(ans-1)


### FIXED CODE ###

from collections import deque

h,w,m=map(int,input().split())
bomb=[list(map(int, input().split())) for _ in range(m)]
res1=[0]*h
res2=[0]*w
for i in range(m):
    bomb1=bomb[i]
    res1[bomb1[0]-1]+=1
    res2[bomb1[1]-1]+=1
ans1=max(res1)
ans2=max(res2)
ans=ans1+ans2
s1=0
l1=deque()
for j in range(h):
    res3=res1[j]
    if res3>s1:
            l1=[j+1]
            s1=res3
    elif res3==s1:
            l1.append(j+1)
s2=0
l2=deque()
for k in range(w):
    res4=res2[k]
    if res4>s2:
            l2=[k+1]
            s2=res4
    elif res4==s2:
            l2.append(k+1)
l3=set(l1)
l4=set(l2)
count=0

for l in range(m):
    bomb2=bomb[l]
    if bomb2[0] in l3 and bomb2[1] in l4:
        count+=1

if count!=len(l1)*len(l2):
    print(ans)
else:
    print(ans-1)