There are N points on the 2D plane, i-th of which is located on (x_i, y_i). There can be multiple points that share the same coordinate. What is the maximum possible Manhattan distance between two distinct points?

Here, the Manhattan distance between two points (x_i, y_i) and (x_j, y_j) is defined by |x_i-x_j| + |y_i-y_j|.

Constraints

* 2 \leq N \leq 2 \times 10^5
* 1 \leq x_i,y_i \leq 10^9
* All values in input are integers.

Input

Input is given from Standard Input in the following format:


N
x_1 y_1
x_2 y_2
:
x_N y_N


Output

Print the answer.

Examples

Input

3
1 1
2 4
3 2


Output

4


Input

2
1 1
1 1


Output

0
/*****Author: Satyajeet Singh************************************/
    import java.io.*;
    import java.util.*;
    import java.text.*; 
    import java.lang.*;
    import java.math.*;
public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));        
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static ArrayList<Integer> graph[];
    static int pptr=0,pptrmax=0;
    static String st[];
/*****************************************Solution Begins***************************************/        
    
    static TreeMap<Integer,TreeSet<Integer>> df(int input[][]){
        TreeMap<Integer,TreeSet<Integer>> map=new TreeMap<>();
        for(int ar[]:input){
            if(!map.containsKey(ar[0])){
                TreeSet<Integer> set=new TreeSet<>();
                set.add(ar[1]);
                map.put(ar[0],set);
            }
            else{
                TreeSet<Integer> set=map.get(ar[0]);
                set.add(ar[1]);
            }
        }
        return map;
    }
    static long mxans(int x,int y,TreeMap<Integer,TreeSet<Integer>> map){
        int a=map.lastKey();
        TreeSet<Integer> set=map.get(a);
        long ans=Math.abs(a-x)+Math.max(Math.abs(set.last()-y),Math.abs(set.first()-y));
        a=map.firstKey();
        set=map.get(a);
        ans=Math.max(ans,Math.abs(a-x)+Math.max(Math.abs(set.last()-y),Math.abs(set.first()-y)));

        return ans;
    }
    public static void main(String args[]) throws Exception{
        int n=pi();
        int input1[][]=new int[n][2];
        int input2[][]=new int[n][2];
        for(int i=0;i<n;i++){
            input1[i][0]=pi();
            input1[i][1]=pi();
            input2[i][1]=input1[i][0];
            input2[i][0]=input1[i][1];
        }        
        TreeMap<Integer,TreeSet<Integer>>map1=df(input1);
        TreeMap<Integer,TreeSet<Integer>>map2=df(input2);
        long ans=0;
        for(int ar[]:input1){
            ans=Math.max(ans,mxans(ar[0],ar[1],map1));
            ans=Math.max(ans,mxans(ar[1],ar[0],map2));
        }
        Arrays.sort(input1,(A,B)->{
            return (A[0]+A[1])-(B[0]+B[1]);
        });
        ans=Math.max(ans,(input1[n-1][0]+input1[n-1][1])-(input1[0][0]+input1[0][1]));
        Arrays.sort(input1,(A,B)->{
            return (A[0]-A[1])-(B[0]-B[1]);
        });
        ans=Math.max(ans,(input1[n-1][0]-input1[n-1][1])-(input1[0][0]-input1[0][1]));
        out.println(ans);
/****************************************Solution Ends**************************************************/
        clr();
    }
    static void clr(){
        out.flush();
        out.close();
    }
    static void nl() throws Exception{
        pptr=0;
        st=br.readLine().split(" ");
        pptrmax=st.length;
    }
    static void nls() throws Exception{
        pptr=0;
        st=br.readLine().split("");
        pptrmax=st.length;
    }
    static int pi() throws Exception{
        if(pptr==pptrmax)
            nl();
        return Integer.parseInt(st[pptr++]);
    }
    static long pl() throws Exception{
        if(pptr==pptrmax)
            nl();
        return Long.parseLong(st[pptr++]);
    }
    static double pd() throws Exception{
        if(pptr==pptrmax)
            nl();
        return Double.parseDouble(st[pptr++]);
    }
    static String ps() throws Exception{
        if(pptr==pptrmax)
            nl();
        return st[pptr++];
    }
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.00000000000"); 
        out.println(ft.format(d));
    }
/**************************************Bit Manipulation**************************************************/
    static int countBit(long mask){
        int ans=0;
        while(mask!=0){
            mask&=(mask-1);
            ans++;
        }
        return ans;
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new ArrayList[n];
        for(int i=0;i<n;i++)
            graph[i]=new ArrayList<>();
    }
    static void addEdge(int a,int b){
        graph[a].add(b);
    }
    // static void addEdge(int a,int b,int c){
    //     graph[a].add(new Pair(b,c));
    // }    
/*********************************************PAIR********************************************************/
    static class Pair{
        int u;
        int v;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }
        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/******************************************Long Pair*******************************************************/
    static class Pairl{
        long u;
        long v;
        public Pairl(long u, long v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pairl other = (Pairl) o;
            return u == other.u && v == other.v;
        }
        public String toString() {
            return "[u=" + u + ", v=" + v + "]";
        }
    }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o){
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c){
        long x=1,y=a%c;
        while(b > 0){
            if(b%2 == 1)
                x=(x*y)%c;
            y = (y*y)%c;
            b = b>>1;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y){
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; 
        b = (x < y) ? x : y;
        r = b;
        while(a % b != 0){
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
}