#include <bits/stdc++.h>
using namespace std;
const int maxn = 200500;
map<int, bool> xs;
map<int, vector<int> > pts;
map<int, int> id;
int cur = 1;
int tree[4 * maxn];
void update(int node, int lo, int hi, int el) {
  if (lo == hi) {
    assert(lo == el);
    tree[node] = 1;
    return;
  }
  int mid = (lo + hi) >> 1;
  if (el <= mid)
    update(2 * node + 1, lo, mid, el);
  else
    update(2 * node + 2, mid + 1, hi, el);
  tree[node] = tree[2 * node + 1] + tree[2 * node + 2];
}
int query(int node, int lo, int hi, int ql, int qh) {
  if (ql > qh || lo > qh || hi < ql) return 0;
  if (ql <= lo && hi <= qh) return tree[node];
  int mid = (lo + hi) >> 1;
  return query(2 * node + 1, lo, mid, ql, qh) +
         query(2 * node + 2, mid + 1, hi, ql, qh);
}
long long get(long long x) { return x * (x + 1) / 2LL; }
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  set<int> p;
  for (int i = 0; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    p.insert(x);
    pts[-y].push_back(x);
  }
  for (auto x : p) id[x] = cur++;
  long long ans = 0, cnt = 0;
  for (auto y : pts) {
    vector<int> v;
    v.push_back(0);
    for (auto x : y.second)
      if (!xs[x]) {
        cnt++;
        update(0, 0, n + 1, id[x]);
        v.push_back(id[x]);
        xs[x] = true;
      } else
        v.push_back(id[x]);
    v.push_back(n + 1);
    sort(v.begin(), v.end());
    ans += get(cnt);
    for (int i = 0; i < (int)v.size() - 1; ++i) {
      ans -= get(query(0, 0, n + 1, v[i] + 1, v[i + 1] - 1));
    }
  }
  cout << ans << '\n';
  return 0;
}
