#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000 + 10;
const double EPS = 1e-7;
struct P {
  double first, second, z;
  P() : first(0), second(0), z(0) {}
  P(double first, double second, double z)
      : first(first), second(second), z(z) {}
  void R() { cin >> z >> first >> second; }
  P operator+(const P &b) const {
    return P(first + b.first, second + b.second, z + b.z);
  }
  P operator-(const P &b) const {
    return P(first - b.first, second - b.second, z - b.z);
  }
  P operator*(double k) const { return P(first * k, second * k, z * k); }
  P operator/(double b) const {
    if (fabs(b) < EPS) return *this;
    return P(first / b, second / b, z / b);
  }
  double len() const {
    return sqrt(((first) * (first)) + ((second) * (second)) + ((z) * (z)));
  }
  bool Z() const {
    return (fabs(first) < EPS && fabs(second) < EPS && fabs(z) < EPS);
  }
  bool operator==(const P &b) const { return ((*this) - b).Z(); }
  void Adj() {
    if (first < 0) first = -first, second = -second, z = -z;
    if (fabs(first) < EPS && second < 0) second = -second, z = -z;
  }
  void Print() const { printf("(%.3lf,%.3lf,%.3lf)\n", first, second, z); }
  bool operator<(const P &b) const {
    if (fabs(first - b.first) > EPS) return first < b.first;
    if (fabs(second - b.second) > EPS) return second < b.second;
    if (fabs(z - b.z) > EPS) return z < b.z;
    return false;
  }
};
double dot(const P &a, const P &b) {
  return a.first * b.first + a.second * b.second + a.z * b.z;
}
P det(const P &a, const P &b) {
  return P(a.second * b.z - a.z * b.second, a.z * b.first - a.first * b.z,
           a.first * b.second - b.first * a.second);
}
struct L {
  P p, v;
  L() : p(0, 0, 0), v(1, 0, 0) {}
  L(const P &p, const P &v) : p(p), v(v) {}
  P X() const { return p; }
  P Y() const { return p + v; };
};
P proj(const P &a, const P &b) { return b * dot(a, b) / dot(b, b); }
P L_L_intersect(const L &a, const L &b) {
  P v1 = det(a.v, b.v), v2 = det(b.p - a.p, b.v);
  return a.p + a.v * (dot(v2, v1) / dot(v1, v1));
}
P closest(L a, const L &b) {
  if (det(a.v, b.v).len() < EPS) return b.p;
  a.p = a.p - proj(a.p - b.p, det(a.v, b.v));
  return L_L_intersect(a, b);
}
struct R4 {
  double v[4];
  R4() {}
  R4(double a, double b, double c, double d) {
    v[0] = a, v[1] = b, v[2] = c, v[3] = d;
    init();
  }
  void init() {
    for (int i = 0; i < 4; ++i)
      if (fabs(v[i]) > EPS) {
        double t = v[i];
        for (int j = i; j < 4; ++j) v[j] /= t;
        break;
      }
  }
  bool operator<(const R4 &b) const {
    for (int i = 0; i < 4; ++i)
      if (fabs(v[i] - b.v[i]) > EPS) return v[i] < b.v[i];
    return false;
  }
};
L line[MAXN];
R4 dir[MAXN];
int n;
void init() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    P a, b;
    a.R();
    b.R();
    line[i] = L(a, b - a);
    dir[i] = R4(0.0, b.first - a.first, b.second - a.second, b.z - a.z);
  }
}
void solve() {
  map<R4, set<R4> > plane;
  map<P, set<int> > point;
  int Tohka = 1;
  for (int i = 1; i <= n; ++i)
    for (int j = i + 1; j <= n; ++j) {
      P h = det(line[i].v, line[j].v);
      if (h.len() > EPS) {
        P a = closest(line[i], line[j]);
        P b = closest(line[j], line[i]);
        if ((a - b).len() < EPS) {
          P c = (a + b) / 2.0;
          R4 w = R4(h.first, h.second, h.z, -dot(h, c));
          point[c].insert(i), point[c].insert(j);
          plane[w].insert(dir[i]), plane[w].insert(dir[j]);
        }
      }
    }
  for (map<P, set<int> >::iterator it = point.begin(); it != point.end(); ++it)
    Tohka = max(Tohka, (int)it->second.size());
  for (map<R4, set<R4> >::iterator it = plane.begin(); it != plane.end(); ++it)
    Tohka = max(Tohka, (int)it->second.size());
  cout << Tohka << endl;
}
int main() {
  init();
  solve();
  fclose(stdin);
  fclose(stdout);
  return 0;
}
