#include <bits/stdc++.h>
using namespace std;
int n;
class point {
 public:
  int x, y;
  bool operator<(const point &t) const {
    if (y != t.y) return y > t.y;
    return x < t.x;
  }
} p[200010];
inline int lowbit(int x) { return x & (-x); }
int endx, endy;
class tree {
 public:
  int dat[200010];
  bool vis[200010];
  void modify(int p) {
    if (!vis[p]) {
      vis[p] = 1;
      for (; p < endx; p += lowbit(p)) dat[p]++;
    }
  }
  int query(int p) {
    int out = 0;
    for (; p; p -= lowbit(p)) out += dat[p];
    return out;
  }
  int query(int l, int r) {
    if (l > r) return 0;
    return query(r) - query(l - 1);
  }
} T;
long long ans;
int lsx[200010], lsy[200010];
vector<point> v[200010];
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &p[i].x, &p[i].y);
    lsx[i] = p[i].x;
    lsy[i] = p[i].y;
  }
  sort(lsx + 1, lsx + n + 1);
  sort(lsy + 1, lsy + n + 1);
  endx = unique(lsx + 1, lsx + n + 1) - lsx;
  endy = unique(lsy + 1, lsy + n + 1) - lsy;
  for (int i = 1; i <= n; i++) {
    p[i].x = lower_bound(lsx + 1, lsx + endx, p[i].x) - lsx;
    p[i].y = lower_bound(lsy + 1, lsy + endy, p[i].y) - lsy;
  }
  sort(p + 1, p + n + 1);
  for (int i = 1; i <= n; i++) v[p[i].y].push_back(p[i]);
  for (int i = endy - 1; i >= 1; i--) {
    for (int j = 0; j < v[i].size(); j++) {
      int l = T.query(v[i][j].x - 1),
          r = T.query(v[i][j].x + 1,
                      (j + 1 == v[i].size() ? endx - 1 : v[i][j + 1].x - 1));
      ans += 1ll * (l + 1) * (r + 1);
      T.modify(v[i][j].x);
    }
  }
  printf("%lld\n", ans);
  return 0;
}
