#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int MOD = 1e9 + 7;
int cnt[200000];
int tree[800010];
int query(int l, int r, int no, int nl, int nr) {
  if (r <= nl || nr <= l) return 0;
  if (l <= nl && nr <= r) return tree[no];
  int mid = (nl + nr) / 2;
  return query(l, r, 2 * no, nl, mid) + query(l, r, 2 * no + 1, mid, nr);
}
int query(int l, int r, int n) { return query(l, r, 1, 0, n); }
int update(int idx, int val, int no, int nl, int nr) {
  if (idx < nl || nr <= idx) return tree[no];
  if (nl + 1 == nr && nl == idx) {
    cnt[idx] += val;
    if (cnt[idx] == 0)
      return tree[no] = 0;
    else
      return tree[no] = 1;
  }
  int mid = (nl + nr) / 2;
  return tree[no] = update(idx, val, 2 * no, nl, mid) +
                    update(idx, val, 2 * no + 1, mid, nr);
}
int update(int idx, int val, int n) { return update(idx, val, 1, 0, n); }
struct Point {
  int x, y;
  bool operator<(const Point &rhs) const {
    if (y != rhs.y) return y < rhs.y;
    return x < rhs.x;
  }
};
vector<Point> po;
vector<vector<Point> > po2;
vector<int> usex;
void compress() {
  for (int i = 0; i < po.size(); i++) usex.push_back(po[i].x);
  sort(usex.begin(), usex.end());
  usex.erase(unique(usex.begin(), usex.end()), usex.end());
  int last = 0;
  po2.push_back(vector<Point>());
  po2[0].push_back(po[0]);
  for (int i = 1; i < po.size(); i++) {
    if (po2[last].back().y == po[i].y)
      po2[last].push_back(po[i]);
    else {
      po2.push_back(vector<Point>());
      last++;
      po2[last].push_back(po[i]);
    }
  }
}
int getCX(int x) {
  return lower_bound(usex.begin(), usex.end(), x) - usex.begin();
}
int main() {
  int n;
  long long int ans = 0;
  scanf("%d", &n);
  for (int i = 0; i < n; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    po.push_back({x, y});
  }
  sort(po.begin(), po.end());
  compress();
  for (int i = po2.size() - 1; i >= 0; i--) {
    for (Point p : po2[i]) update(getCX(p.x), 1, n);
    for (int j = 0; j < po2[i].size(); j++) {
      long long int lnum, rnum;
      if (j == 0)
        lnum = query(0, getCX(po2[i][j].x), n);
      else
        lnum = query(getCX(po2[i][j - 1].x) + 1, getCX(po2[i][j].x), n);
      rnum = query(getCX(po2[i][j].x) + 1, n, n);
      ans += (lnum + 1) * (rnum + 1);
    }
  }
  printf("%lld\n", ans);
  return 0;
}
