#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5;
struct Point {
  int x, y;
};
int N;
Point point[MAXN + 10];
vector<int> xcomp, ycomp;
vector<int> arr[MAXN + 10];
int tree[MAXN + 10];
int query(int i) {
  int ret = 0;
  for (; i > 0; i -= (i & -i)) ret += tree[i];
  return ret;
}
int query(int l, int r) { return query(r) - query(l - 1); }
void update(int i, int val) {
  val = val - query(i, i);
  for (; i <= MAXN; i += (i & -i)) tree[i] += val;
}
long long ans = 0;
int main() {
  int i, j;
  scanf("%d", &N);
  for (i = 1; i <= N; i++) {
    scanf("%d%d", &point[i].x, &point[i].y);
    xcomp.push_back(point[i].x);
    ycomp.push_back(point[i].y);
  }
  sort(xcomp.begin(), xcomp.end());
  xcomp.erase(unique(xcomp.begin(), xcomp.end()), xcomp.end());
  sort(ycomp.begin(), ycomp.end());
  ycomp.erase(unique(ycomp.begin(), ycomp.end()), ycomp.end());
  for (i = 1; i <= N; i++) {
    point[i].x =
        lower_bound(xcomp.begin(), xcomp.end(), point[i].x) - xcomp.begin() + 1;
    point[i].y =
        lower_bound(ycomp.begin(), ycomp.end(), point[i].y) - ycomp.begin() + 1;
    arr[point[i].y].push_back(point[i].x);
  }
  for (i = 1; i <= ycomp.size(); i++) sort(arr[i].begin(), arr[i].end());
  for (i = ycomp.size(); i >= 1; i--) {
    vector<int>& now = arr[i];
    for (j = 0; j < now.size(); j++) update(now[j], 1);
    ans += (long long)query(1, now[0]) * query(now[0], MAXN);
    for (j = 1; j < now.size(); j++) {
      ans += (long long)query(now[j - 1] + 1, now[j]) * query(now[j], MAXN);
    }
  }
  printf("%lld", ans);
}
