You are given a set of n points in a 2D plane. No three points are collinear.

A pentagram is a set of 5 points A,B,C,D,E that can be arranged as follows. <image> Note the length of the line segments don't matter, only that those particular intersections exist.

Count the number of ways to choose 5 points from the given set that form a pentagram.

Input

The first line contains an integer n (5 ≤ n ≤ 300) — the number of points.

Each of the next n lines contains two integers x_i, y_i (-10^6 ≤ x_i,y_i ≤ 10^6) — the coordinates of the i-th point. It is guaranteed that no three points are collinear.

Output

Print a single integer, the number of sets of 5 points that form a pentagram.

Examples

Input


5
0 0
0 2
2 0
2 2
1 3


Output


1


Input


5
0 0
4 0
0 4
4 4
2 3


Output


0


Input


10
841746 527518
595261 331297
-946901 129987
670374 -140388
-684770 309555
-302589 415564
-387435 613331
-624940 -95922
945847 -199224
24636 -565799


Output


85

Note

A picture of the first sample: <image> A picture of the second sample: <image> A picture of the third sample: <image>
#include <bits/stdc++.h>
using namespace std;
struct point {
  long long x, y;
  int first, second;
  point(long long _x = 0, long long _y = 0) : x(_x), y(_y) {}
  point &operator+=(const point &other) {
    x += other.x;
    y += other.y;
    return *this;
  }
  point &operator-=(const point &other) {
    x -= other.x;
    y -= other.y;
    return *this;
  }
  point operator+(const point &other) const { return point(*this) += other; }
  point operator-(const point &other) const { return point(*this) -= other; }
  bool operator==(const point &other) const {
    return x == other.x && y == other.y;
  }
  bool operator!=(const point &other) const { return !(*this == other); }
  point operator-() const { return point(-x, -y); }
  bool top_half() const { return y > 0 || (y == 0 && x > 0); }
};
long long cross(const point &a, const point &b) {
  return (long long)a.x * b.y - (long long)b.x * a.y;
}
long long dot(const point &a, const point &b) {
  return (long long)a.x * b.x + (long long)a.y * b.y;
}
long long norm(const point &p) { return dot(p, p); }
const bool CHECK_OVERFLOW64 = true;
int cross_sign(const point &a, const point &b) {
  if (CHECK_OVERFLOW64) {
    double double_value = (double)a.x * b.y - (double)b.x * a.y;
    if (abs(double_value) > 1e18) return double_value > 0 ? +1 : -1;
  }
  uint64_t uint64_value = (uint64_t)a.x * b.y - (uint64_t)b.x * a.y;
  if (uint64_value == 0) return 0;
  return uint64_value < 9e18 ? +1 : -1;
}
bool left_turn(const point &a, const point &b, const point &c) {
  return cross_sign(b - a, c - b) > 0;
}
double dist(const point &a, const point &b) { return sqrt(norm(a - b)); }
bool yx_compare(const point &a, const point &b) { return (b - a).top_half(); }
bool angle_compare(const point &a, const point &b) {
  if (a.top_half() ^ b.top_half()) return a.top_half();
  return cross_sign(a, b) > 0;
}
const int N_MAX = 305;
const int K = 5;
int N;
vector<point> points;
vector<point> segments;
long long dp[N_MAX][N_MAX][K + 1];
int main() {
  cin >> N;
  points.resize(N);
  for (point &p : points) cin >> p.x >> p.y;
  sort(points.begin(), points.end(), yx_compare);
  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      if (i != j) {
        segments.push_back(points[j] - points[i]);
        segments.back().first = i;
        segments.back().second = j;
      }
  sort(segments.begin(), segments.end(), angle_compare);
  memset(dp, 0, sizeof(dp));
  for (int i = 0; i < N; i++) dp[i][i][0] = 1;
  for (auto &segment : segments)
    for (int i = 0; i <= min(segment.first, segment.second); i++)
      for (int k = 0; k < K; k++)
        dp[i][segment.second][k + 1] += dp[i][segment.first][k];
  long long total = 0;
  for (int i = 0; i < N; i++) total += dp[i][i][K];
  cout << total << '\n';
}
