""" 殴るのが正解…? チェビシェフ距離に置き換えられる 典型っぽいからちゃんと解いておこう 各点について、最遠点と最近点を求められれば終わり 最大は、X+Y,X-Y の最大・最小だけ考えればいいんだった """ import sys from sys import stdin #0-indexed , 半開区間[a,b) #calc変更で演算変更 class SegTreeMin: def __init__(self,N,first): self.NO = 2**(N-1).bit_length() self.First = first self.data = [first] * (2*self.NO) def calc(self,l,r): return min(l,r) def update(self,ind,x): ind += self.NO - 1 self.data[ind] = x while ind >= 0: ind = (ind - 1)//2 self.data[ind] = self.calc(self.data[2*ind+1],self.data[2*ind+2]) def query(self,l,r): L = l + self.NO R = r + self.NO s = self.First while L < R: if R & 1: R -= 1 s = self.calc(s , self.data[R-1]) if L & 1: s = self.calc(s , self.data[L-1]) L += 1 L >>= 1 R >>= 1 return s def get(self , ind): ind += self.NO - 1 return self.data[ind] #0-indexed , 半開区間[a,b) #calc変更で演算変更 class SegTreeMax: def __init__(self,N,first): self.NO = 2**(N-1).bit_length() self.First = first self.data = [first] * (2*self.NO) def calc(self,l,r): return max(l,r) def update(self,ind,x): ind += self.NO - 1 self.data[ind] = x while ind >= 0: ind = (ind - 1)//2 self.data[ind] = self.calc(self.data[2*ind+1],self.data[2*ind+2]) def query(self,l,r): L = l + self.NO R = r + self.NO s = self.First while L < R: if R & 1: R -= 1 s = self.calc(s , self.data[R-1]) if L & 1: s = self.calc(s , self.data[L-1]) L += 1 L >>= 1 R >>= 1 return s def get(self , ind): ind += self.NO - 1 return self.data[ind] inf = float("inf") N = int(stdin.readline()) XY = [] for i in range(N): X,Y = map(int,stdin.readline().split()) XY.append( (X,Y) ) XY.sort() # 各頂点について、最遠点を求める # まず、X+Y,X-Y の最大・最小を集める a,b,A,B = inf,inf,-inf,-inf for X,Y in XY: p = X+Y m = X-Y a = min(a,p) A = max(A,p) b = min(b,m) B = max(B,m) # 後は4通り試す XD = [0] * N for i,(X,Y) in enumerate(XY): p = X+Y m = X-Y XD[i] = max( abs(a-p) , abs(A-p) , abs(b-m) , abs(B-m) ) #print (XD) # 最近点を考える SSS = 500000 foot = SSS//2 ND = [inf] * N segAX = SegTreeMax(SSS,float("-inf")) segBX = SegTreeMax(SSS,float("-inf")) for i,(X,Y) in enumerate(XY): a = X+Y b = X-Y ND[i] = min(ND[i] , a - segAX.query(0,foot+Y) , b - segBX.query(foot+Y,SSS)) if segAX.get(foot+Y) < a: segAX.update(foot+Y,a) if segBX.get(foot+Y) < b: segBX.update(foot+Y,b) segAN = SegTreeMin(SSS,inf) segBN = SegTreeMin(SSS,inf) for i,(X,Y) in enumerate(reversed(XY)): i = N-1-i a = X+Y b = X-Y ND[i] = min(ND[i] , segBN.query(0,foot+Y) - b , segAN.query(foot+Y,SSS) - a) if segAN.get(foot+Y) > a: segAN.update( foot+Y , a ) if segBN.get(foot+Y) > b: segBN.update( foot+Y , b ) #print (ND) ans = inf for x,n in zip(XD,ND): ans = min(ans , x-n) print (ans)