#include <bits/stdc++.h>
using namespace std;
struct point {
int x, y;
};
enum dir {
RIGHT,
LEFT,
UP,
DOWN
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n;
vector<point> a(n);
for (auto &[x, y] : a) {
cin >> x >> y;
}
vector<dir> dirs;
int ans = 0;
auto calc = [&]() {
set<int> infected;
infected.insert(0);
auto intersect_at = [&](int i, int j) {
if (dirs[i] == dirs[j]) {
return -1;
}
if (dirs[i] > dirs[j]) {
swap(i, j);
}
if (dirs[i] == RIGHT) {
if (dirs[j] == LEFT) {
// (a[i].x + t, a[i].y) = (a[j].x - t, a[j].y)
if ((a[j].x - a[i].x) % 2 != 0 || a[j].x - a[i].x < 0 || a[i].y != a[j].y) {
return -1;
}
return (a[j].x - a[i].x) / 2;
} else if (dirs[j] == UP) {
// (a[i].x + t, a[i].y) = (a[j].x, a[j].y + t)
if (a[j].x - a[i].x != a[i].y - a[j].y || a[j].x - a[i].x < 0) {
return -1;
}
return a[j].x - a[i].x;
} else if (dirs[j] == DOWN) {
// (a[i].x + t, a[i].y) = (a[j].x, a[j].y - t)
if (a[j].x - a[i].x != a[j].y - a[i].y || a[j].x - a[i].x < 0) {
return -1;
}
return a[j].x - a[i].x;
}
assert(false);
} else if (dirs[i] == LEFT) {
if (dirs[j] == UP) {
// (a[i].x - t, a[i].y) = (a[j].x, a[j].y + t)
if (a[i].x - a[j].x != a[i].y - a[j].y || a[i].x - a[j].x < 0) {
return -1;
}
return a[i].x - a[j].x;
} else if (dirs[j] == DOWN) {
// (a[i].x - t, a[i].y) = (a[j].x, a[j].y - t)
if (a[i].x - a[j].x != a[j].y - a[i].y || a[i].x - a[j].x < 0) {
return -1;
}
return a[i].x - a[j].x;
}
assert(false);
} else if (dirs[i] == UP) {
if (dirs[j] == DOWN) {
// (a[i].x, a[i].y + t) = (a[j].x, a[j].y - t)
// a[i].y + t = a[j].y - t
// 2t = a[j].y - a[i].y
if ((a[j].y - a[i].y) % 2 != 0 || a[j].y - a[i].y < 0 || a[i].x != a[j].x) {
return -1;
}
return (a[j].y - a[i].y) / 2;
}
assert(false);
}
assert(false);
};
vector<pair<int, pair<int, int>>> events;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
int t = intersect_at(i, j);
if (t != -1) {
events.push_back({t, {i, j}});
}
}
}
sort(events.rbegin(), events.rend());
while (!events.empty()) {
auto [i, j] = events.back().second;
events.pop_back();
if (infected.count(i) || infected.count(j)) {
infected.insert(i);
infected.insert(j);
}
}
return int(infected.size());
};
auto recur = [&](auto &&self, int i) {
if (i == n) {
ans = max(ans, calc());
return;
}
for (int j = 0; j < 4; ++j) {
dirs.push_back(dir(j));
self(self, i + 1);
dirs.pop_back();
}
};
recur(recur, 0);
cout << ans << '\n';
}