#include <bits/stdc++.h>
using namespace std;
#define rand() (rand() | rand() << 16)
#define LSB(x) ((x) & -(x))
int prim(vector<vector<pair<int, int>>>& graph, int startVertex) {
int N = graph.size();
// Priority queue to store the edges and their weights
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
// Create a vector to track visited vertices
vector<bool> visited(N, false);
// Add the starting vertex to the priority queue
pq.push(make_pair(0, startVertex));
vector<pair<int, int>> mst; // Minimum spanning tree
while (!pq.empty()) {
// Extract the minimum weight edge from the priority queue
pair<int, int> curr = pq.top();
pq.pop();
int weight = curr.first;
int vertex = curr.second;
if (visited[vertex]) {
continue;
}
// Mark the current vertex as visited
visited[vertex] = true;
// Add the current edge to the minimum spanning tree
mst.push_back(make_pair(weight, vertex));
// Iterate through all adjacent vertices of the current vertex
for (pair<int, int>& edge : graph[vertex]) {
int adjVertex = edge.first;
int adjWeight = edge.second;
if (!visited[adjVertex]) {
// Add the adjacent vertex and its weight to the priority queue
pq.push(make_pair(adjWeight, adjVertex));
}
}
}
// Find the maximum weight among the edges in the MST
int maxWeight = 0;
for (pair<int, int>& edge : mst) {
maxWeight = max(maxWeight, edge.first);
}
return maxWeight;
}
struct Pt {
int x, y;
};
int c1(Pt p) { return - p.x + p.y; }
int c2(Pt p) { return + p.x - p.y; }
int c3(Pt p) { return - p.x - p.y; }
int c4(Pt p) { return + p.x + p.y; }
int d1(Pt p) { return + p.x + p.y; }
int d2(Pt p) { return + p.x + p.y; }
int d3(Pt p) { return - p.x + p.y; }
int d4(Pt p) { return - p.x + p.y; }
int main() {
// ifstream fin("be2.txt");
// cin.rdbuf(fin.rdbuf());
int N;
cin >> N;
vector<Pt> v(N);
for (int i = 0; i < N; i++) {
cin >> v[i].x >> v[i].y;
}
vector<int> w(N);
iota(w.begin(), w.end(), 0);
vector<vector<pair<int, int>>> g(N);
vector<vector<int>> f(N + 1);
vector<vector<int>> t(N + 1);
// octant 1
sort(w.begin(), w.end(), [&](auto a, auto b) { return v[a].y > v[b].y; });
for (int i = 1; i <= N; i++) {
int s = i - LSB(i);
int e = i;
f[i].assign(w.begin() + s, w.begin() + e);
t[i].resize(e - s);
sort(f[i].begin(), f[i].end(), [&](auto a, auto b) { return c1(v[a]) < c1(v[b]); });
for (int j = 0, m = 0; j < e - s; j++) {
if (d1(v[f[i][j]]) < d1(v[f[i][m]])) {
m = j;
}
t[i][j] = f[i][m];
}
}
for (int i = 0; i < N; i++) {
int l = i, h = N - 1;
while (l != h) {
int m = (l + h + 1) / 2;
if (v[w[m]].y == v[w[i]].y) {
l = m;
}
else {
h = m - 1;
}
}
int r = -1;
for (int j = l; j > 0; j -= LSB(j)) {
l = -1, h = f[j].size() - 1;
while (l != h) {
int m = (l + h + 1) / 2;
if (c1(v[f[j][m]]) < c1(v[w[i]])) {
l = m;
}
else {
h = m - 1;
}
}
if (l >= 0 && (r == -1 || d1(v[t[j][l]]) < d1(v[r]))) {
r = t[j][l];
}
}
if (r != -1) {
g[w[i]].push_back({r, d1(v[r]) - d1(v[w[i]])});
g[r].push_back({w[i], d1(v[r]) - d1(v[w[i]])});
}
}
// octant 4
for (int i = 1; i <= N; i++) {
int s = i - LSB(i);
int e = i;
sort(f[i].begin(), f[i].end(), [&](auto a, auto b) { return c4(v[a]) < c4(v[b]); });
for (int j = 0, m = 0; j < e - s; j++) {
if (d4(v[f[i][j]]) < d4(v[f[i][m]])) {
m = j;
}
t[i][j] = f[i][m];
}
}
for (int i = 0; i < N; i++) {
int l = i, h;
int r = -1;
for (int j = l; j > 0; j -= LSB(j)) {
l = -1, h = f[j].size() - 1;
while (l != h) {
int m = (l + h + 1) / 2;
if (c4(v[f[j][m]]) <= c4(v[w[i]])) {
l = m;
}
else {
h = m - 1;
}
}
if (l >= 0 && (r == -1 || d4(v[t[j][l]]) < d4(v[r]))) {
r = t[j][l];
}
}
if (r != -1) {
g[w[i]].push_back({r, d4(v[r]) - d4(v[w[i]])});
g[r].push_back({w[i], d4(v[r]) - d4(v[w[i]])});
}
}
// octant 2
sort(w.begin(), w.end(), [&](auto a, auto b) { return v[a].x > v[b].x; });
for (int i = 1; i <= N; i++) {
int s = i - LSB(i);
int e = i;
f[i].assign(w.begin() + s, w.begin() + e);
sort(f[i].begin(), f[i].end(), [&](auto a, auto b) { return c2(v[a]) < c2(v[b]); });
for (int j = 0, m = 0; j < e - s; j++) {
if (d2(v[f[i][j]]) < d2(v[f[i][m]])) {
m = j;
}
t[i][j] = f[i][m];
}
}
for (int i = 0; i < N; i++) {
int l = i, h;
int r = -1;
for (int j = l; j > 0; j -= LSB(j)) {
l = -1, h = f[j].size() - 1;
while (l != h) {
int m = (l + h + 1) / 2;
if (c2(v[f[j][m]]) <= c2(v[w[i]])) {
l = m;
}
else {
h = m - 1;
}
}
if (l >= 0 && (r == -1 || d2(v[t[j][l]]) < d2(v[r]))) {
r = t[j][l];
}
}
if (r != -1) {
g[w[i]].push_back({r, d2(v[r]) - d2(v[w[i]])});
g[r].push_back({w[i], d2(v[r]) - d2(v[w[i]])});
}
}
// octant 3
sort(w.begin(), w.end(), [&](auto a, auto b) { return v[a].x < v[b].x; });
for (int i = 1; i <= N; i++) {
int s = i - LSB(i);
int e = i;
f[i].assign(w.begin() + s, w.begin() + e);
sort(f[i].begin(), f[i].end(), [&](auto a, auto b) { return c3(v[a]) < c3(v[b]); });
for (int j = 0, m = 0; j < e - s; j++) {
if (d3(v[f[i][j]]) < d3(v[f[i][m]])) {
m = j;
}
t[i][j] = f[i][m];
}
}
for (int i = 0; i < N; i++) {
int l = i, h = N - 1;
while (l != h) {
int m = (l + h + 1) / 2;
if (v[w[m]].x == v[w[i]].x) {
l = m;
}
else {
h = m - 1;
}
}
int r = -1;
for (int j = l; j > 0; j -= LSB(j)) {
l = -1, h = f[j].size() - 1;
while (l != h) {
int m = (l + h + 1) / 2;
if (c3(v[f[j][m]]) < c3(v[w[i]])) {
l = m;
}
else {
h = m - 1;
}
}
if (l >= 0 && (r == -1 || d3(v[t[j][l]]) < d3(v[r]))) {
r = t[j][l];
}
}
if (r != -1) {
g[w[i]].push_back({r, d3(v[r]) - d3(v[w[i]])});
g[r].push_back({w[i], d3(v[r]) - d3(v[w[i]])});
}
}
cout << prim(g, 0) << endl;
return 0;
}