#include<vector>
#include<algorithm>
typedef double Data;
class RangeMinimumQuery {
public:
  static const Data INF;
  RangeMinimumQuery(int s) : size_(1) {
    while(size_ < s) size_ <<= 1;
    node_.assign((size_ << 1) - 1, INF);
  }
  Data find(int left, int right) const {
    return query(left, right, 0, 0, size_ - 1);
  }
  void update(int index, Data value) {
    int i = index + size_ - 1;
    node_[i] = value;
    while((i = parent(i)) != NIL) node_[i] = std::min(node_[left_child(i)], node_[right_child(i)]);
  }
private:
  int parent(int node) const {return node == 0 ? NIL : (node - 1) >> 1;}
  int left_child(int node) const {return (node << 1) + 1;}
  int right_child(int node) const {return (node << 1) + 2;}
  Data query(int a, int b, int k, int l, int r) const {
    if(b < l || r < a) return INF;
    if(a <= l && r <= b) return node_[k];
    Data vl = query(a, b, left_child(k), l, (l + r) / 2);
    Data vr = query(a, b, right_child(k), (l + r) / 2 + 1, r);
    return std::min(vl, vr);
  }
  static const int NIL;
  int size_;
  std::vector<Data> node_;
};
const Data RangeMinimumQuery::INF = 1e9;
const int RangeMinimumQuery::NIL = -1;

#include<bits/stdc++.h>
using namespace std;

const double PI = acos(-1.0);

struct Point {double x, y;};
struct Square {double left, right, top, bottom;};

bool include(const Square& s, const Point& p) {
  return s.left <= p.x && p.x <= s.right && s.bottom <= p.y && p.y <= s.top;
}

bool ok(const vector<Point>& point, double d, const RangeMinimumQuery& maxy, const RangeMinimumQuery& miny) {
  int leftA = 0;
  int rightA = upper_bound(begin(point), end(point), point.front().x+d, [](double lhs, const Point& rhs){return lhs < rhs.x;}) - begin(point) - 1;
  int leftB = lower_bound(begin(point), end(point), point.back().x-d, [](const Point& lhs, double val){return lhs.x < val;}) - begin(point);
  int rightB = point.size() - 1;
  if(rightA < leftB) {
    double lowA = miny.find(leftA, rightA), highA = -maxy.find(leftA, rightA);
    double lowB = miny.find(leftB, rightB), highB = -maxy.find(leftB, rightB);
    if(rightA + 1 == leftB) if(highA - lowA <= d && highB - lowB <= d) return true;
  } else {
    Square A = {point.front().x, point.front().x+d, 0, 0};
    Square B = {point.back().x-d, point.back().x, 0, 0};
    A.top = -maxy.find(leftA, rightA);
    A.bottom = A.top - d;
    B.bottom = miny.find(leftB, rightB);
    B.top = B.bottom + d;
    if(all_of(begin(point), end(point), [&](const Point& p){return include(A, p) || include(B, p);})) return true;
    A.bottom = miny.find(leftA, rightA);
    A.top = A.bottom + d;
    B.top = -maxy.find(leftB, rightB);
    B.bottom = B.top - d;
    if(all_of(begin(point), end(point), [&](const Point& p){return include(A, p) || include(B, p);})) return true;
  }
  return false;
}

int main() {
  int N;
  cin >> N;
  vector<Point> point(N);
  for(auto& p: point) cin >> p.x >> p.y;
  for(auto& p: point) p = {p.x * cos(PI/4.0) - p.y * sin(PI/4.0), p.x * sin(PI/4.0) + p.y * cos(PI/4.0)};
  sort(begin(point), end(point), [](const Point& lhs, const Point& rhs){return lhs.x < rhs.x;});
  RangeMinimumQuery maxy(N), miny(N);
  for(int i = 0; i < N; ++i) {
    maxy.update(i, -point[i].y);
    miny.update(i, point[i].y);
  }
  const double EPS = 1e-3;
  double low = -300000.0, high = 300000.0;
  while(EPS < high - low) {
    double middle = (low + high) / 2.0;
    ok(point, middle, maxy, miny) ? (high = middle) : (low = middle);
  }
  cout << int(high * sqrt(2.0)) << endl;
}

Measured memory_bytes: 6804