#include <iostream>
#include <cstdlib>
#include <vector>
#include <iostream>

using namespace std;

class Points {
private:
    vector<int> Xs;
    vector<int> Ys;
    size_t N;
    int getPathLengthBetween2Points(int x1, int y1, int x2, int y2);
    vector<int> findAllPathsBetween(size_t pointIndex1, size_t pointIndex2);
    vector<int> findAllNeighboursToPointWithIndex(size_t pointIndex);
public:
    Points();
    void displayPoints();
    int findLongestOfShortestPaths();
};

Points::Points() {
    do {
        cin >> N;
    } while (N < 0 || N > 2000);
    Xs.resize(N);
    Ys.resize(N);
    for (size_t i = 0; i < N; i++) {
        // get x
        do {
            cin >> Xs[i];
        } while (Xs[i] < 0 || Xs[i] >= 1000);
        // get y
        do {
            cin >> Ys[i];
        } while (Ys[i] < 0 || Ys[i] >= 1000);
    }
}

void Points::displayPoints() {
    for (size_t i = 0; i < N; i++) {
        cout << Xs[i] << " " << Ys[i] << endl;
    }
}

vector<int> Points::findAllNeighboursToPointWithIndex(size_t pointIndex) {
    vector<int> neighbourIndexes;
    for (size_t i = 0; i < N; i++) {
        if (i != pointIndex) {
            // for every point, check if they are neighbours
            if (getPathLengthBetween2Points(Xs[pointIndex], Ys[pointIndex], Xs[i], Ys[i]) != -1) {
                neighbourIndexes.push_back(i);
            }
        }
    }
    return neighbourIndexes;
}

vector<int> Points::findAllPathsBetween(size_t pointIndex1, size_t pointIndex2) {
    vector<int> pathsLengths;
    vector< vector<int>> paths;
    for (size_t i = 0; i < N; i++) {
        if (i != pointIndex1) {
            if (getPathLengthBetween2Points(Xs[pointIndex1], Ys[pointIndex1], Xs[i], Ys[i]) != -1) {
                paths.reserve( paths.size() + 1);
            }
            /*
            // find all of the starting point's neighbours
            vector<int> neighbourIndexes = findAllNeighboursToPointWithIndex(i)
            if (neighbourIndexes.size() == 0) {
                // the point does not have neighbours therefore there isn't a path
                break;
            }
            // we should recurse through all of the neighbours to find a path
            recursivePathFinder();
            */
        }
    }

    return pathsLengths;
}

int Points::getPathLengthBetween2Points(int x1, int y1, int x2, int y2) {
    int length = -1;
    if (x1 == x2 || y1 == y2) {
        length = abs(x1 - x2) + abs(y1 - y2);
    }
    return length;
}

int Points::findLongestOfShortestPaths() {
    int longest = 0;
    // iterate over every point pair to find the shortest path
    for (size_t i = 0; i < N; i++) {
        for (size_t j = 0; j < N; j++) {
            int shortestPath = 0;
            if (i != j) {
                // find the all path lengths between the pair of points
                vector<int> paths = findAllPathsBetween(i, j);
                if (paths.size() > 0) {
                    shortestPath = paths[0];
                    for (size_t k = 0; k < paths.size(); k++) {
                        shortestPath = paths[k];
                    }
                }
            }
            // check if this shortest path is the longest
            if (shortestPath > longest) {
                longest = shortestPath;
            }
        }
    }
    return longest;
}

int main() {
    Points p;
    p.displayPoints();
    cout << p.findLongestOfShortestPaths() << endl;
    return 0;
}


























