#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
long long b[maxn], num[maxn << 2];
struct node {
  long long x, y;
  node(long long x = 0, long long y = 0) : x(x), y(y) {}
  bool operator<(const node& g) const {
    if (y != g.y) return y > g.y;
    return x < g.x;
  }
} a[maxn];
void update(int k, int lef, int rig, int pos) {
  if (lef == rig) {
    num[k] = 1;
    return;
  }
  int mid = (lef + rig) >> 1;
  if (pos <= mid)
    update(k << 1, lef, mid, pos);
  else
    update(k << 1 | 1, mid + 1, rig, pos);
  num[k] = num[k << 1] + num[k << 1 | 1];
}
long long query(int k, int lef, int rig, int l, int r) {
  if (l > r) return 0;
  if (l <= lef && r >= rig) {
    return num[k];
  }
  int mid = (lef + rig) >> 1;
  long long ans = 0;
  if (l <= mid) ans += query(k << 1, lef, mid, l, r);
  if (r > mid) ans += query(k << 1 | 1, mid + 1, rig, l, r);
  return ans;
}
int n;
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%lld%lld", &a[i].x, &a[i].y);
    b[i] = a[i].x;
  }
  sort(b + 1, b + n + 1);
  int sz = unique(b + 1, b + n + 1) - b;
  for (int i = 1; i <= n; i++) a[i].x = lower_bound(b + 1, b + sz, a[i].x) - b;
  sort(a + 1, a + n + 1);
  vector<int> g;
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    update(1, 1, sz, a[i].x);
    g.push_back(i);
    if (i == n || a[i + 1].y != a[i].y) {
      for (int j = 0; j < g.size(); j++) {
        int u = g[j];
        int lb = 1;
        if (j > 0) lb = a[g[j - 1]].x + 1;
        int ub = a[u].x - 1;
        long long t = query(1, 1, sz, lb, ub);
        t++;
        lb = a[u].x + 1;
        ub = sz - 1;
        long long t1 = query(1, 1, sz, lb, ub);
        t1++;
        ans += t * t1;
      }
      g.clear();
    }
  }
  printf("%lld\n", ans);
  return 0;
}
