#include <bits/stdc++.h>
using namespace std;
const int N = 2020;
struct Slope {
  long long x, y;
  bool up;
  Slope() {}
  Slope(long long x, long long y, bool up) : x(x), y(y), up(up) {}
  bool operator<(const Slope& m) const {
    pair<long long, long long> p1 = {y, x};
    pair<long long, long long> p2 = {m.y, m.x};
    return (1LL * p1.first * p2.second < 1LL * p2.first * p1.second);
  }
};
long long gcd(long long a, long long b) { return (b ? gcd(b, a % b) : a); }
pair<long long, long long> getSlope(long long x, long long y) {
  long long G = gcd(x, y);
  x /= G;
  y /= G;
  if (x < 0) {
    x = -x;
    y = -y;
  }
  return {y, x};
}
long long C(long long n, long long k = 2) {
  if (k > n) return 0;
  return n * (n - 1) / 2;
}
vector<Slope> v;
vector<pair<long long, long long>> Point;
long long Sweep(int centerIdx) {
  long long side1 = 0, side2 = 0, Ans = 0;
  for (int i = 0; i < (int)Point.size(); i++)
    if (i != centerIdx) {
      long long x = Point[i].first - Point[centerIdx].first;
      long long y = Point[i].second - Point[centerIdx].second;
      bool up;
      if (x > 0 || (x == 0 && y > 0))
        up = true, side1++;
      else
        up = false, side2++;
      pair<long long, long long> m = getSlope(x, y);
      v.push_back(Slope(m.first, m.second, up));
    }
  sort(v.begin(), v.end());
  for (int i = 0; i < v.size(); i++) {
    if (v[i].up)
      side1--;
    else
      side2--;
    Ans += C(side1) * C(side2);
    if (v[i].up)
      side2++;
    else
      side1++;
  }
  v.clear();
  return Ans;
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    Point.push_back({x, y});
  }
  long long Ans = 0;
  for (int i = 0; i < n; i++) Ans += Sweep(i);
  printf("%I64d\n", Ans / 2);
  return 0;
}
