#include <bits/stdc++.h>
using namespace std;
namespace _ {
bool rEOF = 1;
inline char nc() {
  static char buf[100000], *p1 = buf, *p2 = buf;
  return p1 == p2 && rEOF &&
                 (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2)
             ? (rEOF = 0, EOF)
             : *p1++;
}
template <class _T>
inline bool read(_T &num) {
  char c = nc(), f = 1;
  num = 0;
  while (c < '0' || c > '9') c == '-' && (f = -1), c = nc();
  while (c >= '0' && c <= '9') num = num * 10 + c - '0', c = nc();
  return (bool)(num *= f);
}
inline bool need(char &c) {
  return c >= 'a' && c <= 'z' || c >= '0' && c <= '9' || c >= 'A' && c <= 'Z';
}
inline bool read_str(char *a) {
  while ((*a = nc()) && need(*a) && rEOF) ++a;
  *a = '\0';
  return rEOF;
}
}  // namespace _
using namespace _;
void file(bool opt) {
  if (opt && fopen("in.txt", "r")) {
    freopen("in.txt", "r", stdin);
  }
}
const double eps = 1e-8;
int sgn(double x) {
  if (fabs(x) < eps) return 0;
  if (x < 0)
    return -1;
  else
    return 1;
}
struct Point {
  double x, y;
  Point() {}
  Point(double _x, double _y) {
    x = _x;
    y = _y;
  }
  bool operator==(Point b) const {
    return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;
  }
  bool operator<(Point b) const {
    return sgn(x - b.x) == 0 ? sgn(y - b.y) < 0 : x < b.x;
  }
  Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }
  double operator^(const Point &b) const { return x * b.y - y * b.x; }
} a[1000 + 5];
struct Line {
  Point s, e;
  Line() {}
  Line(Point _s, Point _e) {
    s = _s;
    e = _e;
  }
  bool parallel(Line v) { return sgn((e - s) ^ (v.e - v.s)) == 0; }
  int relation(Point p) {
    int c = sgn((p - s) ^ (e - s));
    if (c < 0)
      return 1;
    else if (c > 0)
      return 2;
    else
      return 3;
  }
  int linecrossline(Line v) {
    if ((*this).parallel(v)) return v.relation(s) == 3;
    return 2;
  }
} b[1000000 + 5];
int cnt = 0;
map<Point, int> Hash;
vector<Line> box[1000000 + 5];
int n;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
int main() {
  read(n);
  long long tot = 0;
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    int x, y;
    read(x), read(y);
    a[i] = Point(x, y);
    for (int j = 1; j < i; j++) {
      Point xl = a[i] - a[j];
      if (sgn(xl.x) < 0) xl.x = -xl.x, xl.y = -xl.y;
      long long g = gcd(xl.x, xl.y);
      xl.x /= g;
      xl.y /= g;
      if (Hash.find(xl) == Hash.end()) Hash[xl] = cnt++;
      bool flag = 1;
      int pos = Hash[xl];
      for (int k = 0; k < box[pos].size() && flag; k++) {
        if (Line(a[i], a[j]).linecrossline(box[pos][k]) == 1) flag = 0;
      }
      if (flag) {
        ans += (tot++) - box[pos].size();
        box[pos].push_back(Line(a[i], a[j]));
      }
    }
  }
  printf("%lld\n", ans);
  return 0;
}
