Problem:
Score : 500 points

Problem Statement

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.

Sample Input 1

3
1 1
2 4
3 2

Sample Output 1

4

The Manhattan distance between the first point and the second point is |1-2|+|1-4|=4, which is maximum possible.

Sample Input 2

2
1 1
1 1

Sample Output 2

0

Solution in Rust (1.42.0) (judge verdict: Accepted)

use ordered_float::OrderedFloat;
use proconio::input;
#[allow(unused_imports)]
use proconio::marker::*;
#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
#[allow(unused_imports)]
use std::f64::consts::*;

#[allow(unused)]
const INF: usize = std::usize::MAX / 4;
#[allow(unused)]
const M: usize = 1000000007;

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),* $(,)*) => {
        #[cfg(debug_assertions)]
        eprintln!(concat!($("| ", stringify!($a), "={:?} "),*, "|"), $(&$a),*);
    };
}

#[derive(Clone, Copy)]
pub struct Point {
    pub x: isize,
    pub y: isize,
}

fn anticlockwise(p0: Point, p1: Point, p2: Point) -> bool {
    let c = (p2.x - p0.x) * (p1.y - p0.y) - (p1.x - p0.x) * (p2.y - p0.y);
    c < 0
}

fn graham_scan(points: &[Point]) -> Result<Vec<(Point, usize)>, String> {
    let n = points.len();
    if n < 3 {
        return Ok(vec![]);
    }
    let p0 = *points.iter().min_by_key(|&p| (p.y, p.x)).unwrap();
    let mut indices = (0..n).collect::<Vec<_>>();
    indices.sort_by_key(|&i| {
        (
            OrderedFloat::from(((points[i].y - p0.y) as f64).atan2((points[i].x - p0.x) as f64)),
            Reverse(OrderedFloat((points[i].x - p0.x) as f64)),
        )
    });
    let mut stack = vec![];
    for &i in &indices[0..3] {
        stack.push((points[i], i));
    }
    for &i in &indices[3..n] {
        loop {
            let m = stack.len();
            if m < 2 || anticlockwise(stack[m - 2].0, stack[m - 1].0, points[i]) {
                break;
            }
            stack.pop();
        }
        stack.push((points[i], i));
    }
    Ok(stack)
}

fn dist(i: usize, j: usize, xy: &Vec<(isize, isize)>) -> isize {
    let (x1, y1) = xy[i];
    let (x2, y2) = xy[j];
    (x1 - x2).abs() + (y1 - y2).abs()
}

fn main() {
    input! {
        n: usize,
        xy: [(isize, isize); n],
    }
    // let mut d = 0;
    // for i in 0..n {
    //     for j in 0..i {
    //         if dist(i, j, &xy) >= d {
    //             debug!(i, j);
    //         }
    //         d = max(d, dist(i, j, &xy));
    //     }
    // }
    // println!("{}", d);

    let points = xy
        .iter()
        .map(|&(x, y)| Point { x, y })
        .collect::<Vec<Point>>();
    let ch = graham_scan(&points).unwrap();

    if ch.len() == 0 {
        let mut d = 0;
        for i in 0..n {
            for j in 0..i {
                d = max(d, dist(i, j, &xy));
            }
        }
        println!("{}", d);
        return;
    }

    if ch.len() < 10000 {
        let mut d = 0;
        for i in 0..ch.len() {
            for j in 0..i {
                d = max(d, dist(ch[i].1, ch[j].1, &xy));
            }
        }
        println!("{}", d);
        return;
    }

    let mut p = vec![];
    for &(_, i) in &ch {
        debug!(xy[i]);
        p.push(i);
    }
    for &(_, i) in &ch {
        p.push(i);
    }
    debug!(p);

    let mut result = 0;
    let mut l = 0;
    for k in 0..ch.len() {
        if l < k {
            l = k;
        }
        let mut d0 = dist(p[k], p[l], &xy);
        let d = loop {
            if l + 1 >= p.len() {
                break d0;
            }
            let d = dist(p[k], p[l + 1], &xy);
            debug!(k, l + 1);
            debug!(xy[p[k]], xy[p[l + 1]]);
            debug!(p[k], p[l + 1], d, d0);
            if d <= d0 {
                if l > k {
                    l -= 1;
                }
                break d0;
            }
            l += 1;
            d0 = d;
        };
        debug!(d);
        result = max(result, d);
    }
    println!("{}", result);
}