#include <bits/stdc++.h>
using namespace std;
namespace mine {
void chmax(int &x, const long long y) { x = (x > y ? x : y); }
void chmin(int &x, const long long y) { x = (x < y ? x : y); }
long long qread() {
  long long ans = 0, f = 1;
  char c = getchar();
  while (c < '0' or c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while ('0' <= c and c <= '9') ans = ans * 10 + c - '0', c = getchar();
  return ans * f;
}
void write(long long num) {
  if (num < 0) putchar('-'), num = -num;
  if (num >= 10) write(num / 10);
  putchar('0' + num % 10);
}
void write1(long long num) {
  write(num);
  putchar(' ');
}
void write2(long long num) {
  write(num);
  putchar('\n');
}
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
void add(long long &a, long long b) {
  a += b;
  if (a >= MOD) a -= MOD;
  if (a <= -MOD) a += MOD;
}
long long qpower(long long x, int e) {
  long long ans = 1;
  while (e) {
    if (e & 1) ans = ans * x % MOD;
    x = x * x % MOD;
    e >>= 1;
  }
  return ans;
}
long long invm(long long x) { return qpower(x, MOD - 2); }
const int MAX_N = 2e5 + 10;
namespace Splay {
struct Nod {
  int son[2], fa, siz, d;
} p[MAX_N];
int root = 0, id = 0;
bool son(int x) { return p[p[x].fa].son[1] == x; }
void pushup(int x) { p[x].siz = 1 + p[p[x].son[0]].siz + p[p[x].son[1]].siz; }
void rotate(int x) {
  int f = p[x].fa, ff = p[f].fa, c = son(x);
  if (ff) p[ff].son[son(f)] = x;
  int tson = p[x].son[c ^ 1];
  p[f].son[c] = tson;
  p[x].son[c ^ 1] = f;
  p[x].fa = ff;
  p[f].fa = x;
  if (tson) p[tson].fa = f;
  pushup(f);
  pushup(x);
}
void splay(int x) {
  for (int f = p[x].fa; p[x].fa > 0; rotate(x), f = p[x].fa)
    if (p[f].fa > 0) son(x) ^ son(f) ? rotate(x) : rotate(f);
  root = x;
}
int findip(int d) {
  int x = root;
  while (p[x].d != d) {
    if (d < p[x].d) {
      if (p[x].son[0] == 0) return x;
      x = p[x].son[0];
    } else {
      if (p[x].son[1] == 0) return x;
      x = p[x].son[1];
    }
  }
  return x;
}
void insert(int d) {
  if (root == 0) {
    p[root = ++id] = (Nod){0, 0, 0, 1, d};
    return;
  }
  int x = findip(d);
  if (p[x].d == d) return;
  int y = ++id;
  p[y] = (Nod){0, 0, x, 1, d};
  p[x].son[d > p[x].d] = y;
  splay(y);
}
int getrk(int d) {
  int x = findip(d);
  splay(x);
  return p[p[x].son[0]].siz + 1;
}
};  // namespace Splay
pair<int, int> pt[MAX_N];
set<int> hash;
bool cmp(pair<int, int> a, pair<int, int> b) {
  return a.second > b.second or (a.second == b.second and a.first < b.first);
}
long long pp(long long x) { return (x + 1) * x / 2; }
void main() {
  int n = qread();
  for (int i = 1; i <= n; i++) {
    int x = qread(), y = qread();
    pt[i] = make_pair(x, y);
  }
  sort(pt + 1, pt + n + 1, cmp);
  long long ans = 0;
  for (int i = 1; i <= n;) {
    int j = i;
    while (j + 1 <= n and pt[i].second == pt[j + 1].second) j++;
    using namespace Splay;
    for (int t = i; t <= j; t++) {
      insert(pt[t].first);
      if (t > i) ans -= pp(getrk(pt[t].first) - getrk(pt[t - 1].first) - 1);
    }
    ans += pp(p[root].siz);
    int x = findip(pt[i].first);
    splay(x);
    ans -= pp(p[p[x].son[0]].siz);
    int y = findip(pt[j].first);
    splay(y);
    ans -= pp(p[p[y].son[1]].siz);
    i = j + 1;
  }
  printf("%lld", ans);
}
};  // namespace mine
int main() {
  srand(time(0));
  mine::main();
}
