#include <bits/stdc++.h>
using namespace std;
const int N_MAX = 1010;
struct Point {
  int x, y;
};
Point points[N_MAX];
int nPoint;
long long calculateGCD(long long a, long long b) {
  while (b > 0) {
    long long c = a % b;
    a = b;
    b = c;
  }
  return a;
}
tuple<int, int, long long> getLine(Point p1, Point p2) {
  int a = p1.y - p2.y;
  int b = p2.x - p1.x;
  long long c = -((long long)a * p1.x + (long long)b * p1.y);
  if (a < 0 || (a == 0 && b < 0)) {
    a = -a;
    b = -b;
    c = -c;
  }
  long long div = calculateGCD(calculateGCD(abs(a), abs(b)), abs(c));
  a /= div;
  b /= div;
  c /= div;
  return make_tuple(a, b, c);
}
void outerInit() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  auto fi = new ifstream("test.inp");
  if (*fi) {
    cin.rdbuf(fi->rdbuf());
  }
}
void readData() {
  cin >> nPoint;
  for (int i = 1; i <= nPoint; ++i) {
    cin >> points[i].x >> points[i].y;
  }
}
void solveData() {
  vector<tuple<int, int, long long>> lines;
  lines.reserve(nPoint * (nPoint - 1) / 2);
  for (int i = 1; i <= nPoint; ++i) {
    for (int j = i + 1; j <= nPoint; ++j) {
      lines.push_back(getLine(points[i], points[j]));
    }
  }
  sort(lines.begin(), lines.end());
  lines.resize(unique(lines.begin(), lines.end()) - lines.begin());
  long long res = 0;
  int i = 0;
  int j = 0;
  while (i < lines.size()) {
    while (j < lines.size() && get<0>(lines[i]) == get<0>(lines[j]) &&
           get<1>(lines[i]) == get<1>(lines[j]))
      ++j;
    res += (long long)(j - i) * (lines.size() - (j - i));
    i = j;
  }
  res /= 2;
  cout << res;
}
int main() {
  outerInit();
  readData();
  solveData();
}
