#include <bits/stdc++.h>
const int maxn = 50 + 5;
struct point {
  int x, y;
} a[maxn];
struct line {
  int ku, kv;
  int bu, bv;
  bool operator<(const line &a) const {
    if (ku != a.ku)
      return ku < a.ku;
    else if (kv != a.kv)
      return kv < a.kv;
    else if (bu != a.bu)
      return bu < a.bu;
    else
      return bv < a.bv;
  }
} b[maxn * maxn];
struct K {
  int u, v;
  K(int U, int V) : u(U), v(V) {}
  bool operator<(const K &a) const {
    if (u != a.u)
      return u < a.u;
    else
      return v < a.v;
  }
};
std::map<K, int> count;
std::set<line> Set;
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
void simp(int &a, int &b) {
  if (!a) b = 1;
  if (!b) a = 1;
  int g = gcd(a, b);
  a /= g;
  b /= g;
  if (a > 0 && b < 0) {
    a *= -1;
    b *= -1;
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    scanf("%d%d", &a[i].x, &a[i].y);
  }
  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      int ku = a[i].y - a[j].y;
      int kv = a[i].x - a[j].x;
      simp(ku, kv);
      b[i].ku = ku;
      b[i].kv = kv;
      if (kv == 0) {
        b[i].bu = a[i].x;
        b[i].bv = 1;
      } else {
        b[i].bu = a[i].y * kv - ku * a[i].x;
        b[i].bv = kv;
        simp(b[i].bu, b[i].bv);
      }
      if (!Set.count(b[i])) {
        Set.insert(b[i]);
      }
    }
  }
  std::set<line>::iterator it;
  for (it = Set.begin(); it != Set.end(); it++) {
    line cur = *it;
    K kk = K(cur.ku, cur.kv);
    if (!count.count(kk)) {
      count[kk] = 1;
    } else
      count[kk] += 1;
  }
  int ans = 0;
  int total = Set.size();
  for (it = Set.begin(); it != Set.end(); it++) {
    line cur = *it;
    K kk = K(cur.ku, cur.kv);
    ans += (total - count[kk]);
  }
  printf("%d\n", ans / 2);
  return 0;
}
