You are given set of n points in 5-dimensional space. The points are labeled from 1 to n. No two points coincide.

We will call point a bad if there are different points b and c, not equal to a, from the given set such that angle between vectors <image> and <image> is acute (i.e. strictly less than <image>). Otherwise, the point is called good.

The angle between vectors <image> and <image> in 5-dimensional space is defined as <image>, where <image> is the scalar product and <image> is length of <image>.

Given the list of points, print the indices of the good points in ascending order.

Input

The first line of input contains a single integer n (1 ≤ n ≤ 103) — the number of points.

The next n lines of input contain five integers ai, bi, ci, di, ei (|ai|, |bi|, |ci|, |di|, |ei| ≤ 103) — the coordinates of the i-th point. All points are distinct.

Output

First, print a single integer k — the number of good points.

Then, print k integers, each on their own line — the indices of the good points in ascending order.

Examples

Input

6
0 0 0 0 0
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1


Output

1
1


Input

3
0 0 1 2 0
0 0 9 2 0
0 0 5 9 0


Output

0

Note

In the first sample, the first point forms exactly a <image> angle with all other pairs of points, so it is good.

In the second sample, along the cd plane, we can see the points look as follows:

<image>

We can see that all angles here are acute, so no points are good.
#include <bits/stdc++.h>
using namespace std;
struct Point {
  double coord[5];
};
Point read_point() {
  Point x;
  for (int i = 0; i < 5; i++) {
    cin >> x.coord[i];
  }
  return x;
}
Point vec(const Point &x, const Point &y) {
  Point ref;
  for (int t = 0; t < 5; t++) {
    ref.coord[t] = x.coord[t] - y.coord[t];
  }
  return ref;
}
bool sign(const Point &x, const Point &y) {
  int sign = 0;
  for (int i = 0; i < 5; i++) {
    sign += x.coord[i] * y.coord[i];
  }
  return sign > 0;
}
vector<Point> a;
vector<int> ans;
bool check(const Point &orig, const vector<Point> &neg) {
  for (int i = 0; i < neg.size(); i++) {
    Point to_check1 = vec(orig, neg[i]);
    for (int j = i + 1; j < neg.size(); j++) {
      Point to_check2 = vec(orig, neg[j]);
      if (sign(to_check1, to_check2)) {
        return false;
      }
    }
  }
  return true;
}
int main() {
  int n;
  cin >> n;
  if (n < 3) {
    cout << n << endl;
    for (int i = 0; i < n; i++) {
      cout << i + 1 << endl;
    }
    return 0;
  }
  a.resize(n);
  for (int i = 0; i < n; i++) {
    a[i] = read_point();
  }
  for (int i = 0; i < n; i++) {
    vector<Point> neg;
    Point ref;
    int st = 1;
    if (i == 0) {
      ref = vec(a[0], a[1]);
      st = 2;
    } else {
      ref = vec(a[i], a[0]);
    }
    int j = st;
    for (; j < n; j++) {
      if (j == i) {
        continue;
      }
      Point to_check = vec(a[i], a[j]);
      if (sign(ref, to_check)) {
        break;
      } else {
        neg.push_back(a[j]);
        if (neg.size() > 30) {
          break;
        }
      }
    }
    if (j != n) {
      continue;
    }
    if (check(a[i], neg)) {
      ans.push_back(i + 1);
    }
  }
  cout << ans.size() << endl;
  for (int i = 0; i < ans.size(); i++) {
    cout << ans[i] << endl;
  }
  return 0;
}
