You are running for a governor in a small city in Russia. You ran some polls and did some research, and for every person in the city you know whom he will vote for, and how much it will cost to bribe that person to vote for you instead of whomever he wants to vote for right now. You are curious, what is the smallest amount of money you need to spend on bribing to win the elections. To win elections you need to have strictly more votes than any other candidate.

Input

First line contains one integer n (1 ≤ n ≤ 105) — number of voters in the city. Each of the next n lines describes one voter and contains two integers ai and bi (0 ≤ ai ≤ 105; 0 ≤ bi ≤ 104) — number of the candidate that voter is going to vote for and amount of money you need to pay him to change his mind. You are the candidate 0 (so if a voter wants to vote for you, ai is equal to zero, in which case bi will also be equal to zero).

Output

Print one integer — smallest amount of money you need to spend to win the elections.

Examples

Input

5
1 2
1 2
1 2
2 1
0 0


Output

3


Input

4
1 2
1 2
2 1
0 0


Output

2


Input

1
100000 0


Output

0
#include <bits/stdc++.h>
using namespace std;
const int N = 121111;
inline int min(int a, int b) { return a < b ? a : b; }
inline int max(int a, int b) { return a > b ? a : b; }
inline int random(int x) {
  srand(x * rand());
  srand(x * x * rand());
  return rand();
}
int t = 0;
struct Treap {
  struct Node {
    int key, fix;
    Node *left, *right;
    int size, sum;
    inline Node(int ikey) {
      key = ikey;
      sum = key;
      size = 1;
      fix = random(ikey);
      left = right = NULL;
    }
  } * root;
  inline Treap() { root = NULL; }
  inline int lsum(Node *&p) { return p->left ? p->left->sum : 0; }
  inline int rsum(Node *&p) { return p->right ? p->right->sum : 0; }
  inline int lsize(Node *&p) { return p->left ? p->left->size : 0; }
  inline int rsize(Node *&p) { return p->right ? p->right->size : 0; }
  inline void maintain(Node *&p) {
    if (!p) return;
    p->size = lsize(p) + rsize(p) + 1;
    p->sum = lsum(p) + rsum(p) + p->key;
  }
  inline void LR(Node *&p) {
    Node *q = p->right;
    p->right = q->left;
    q->left = p;
    p = q;
    maintain(p->left);
    maintain(p);
  }
  inline void RR(Node *&p) {
    Node *q = p->left;
    p->left = q->right;
    q->right = p;
    p = q;
    maintain(p->right);
    maintain(p);
  }
  inline void insert(int ikey, Node *&p) {
    t++;
    if (!p)
      p = new Node(ikey);
    else if (ikey < p->key) {
      insert(ikey, p->left);
      maintain(p);
      if (p->fix > p->left->fix) RR(p);
    } else {
      insert(ikey, p->right);
      maintain(p);
      if (p->fix > p->right->fix) LR(p);
    }
  }
  inline void Insert(int ikey) { insert(ikey, root); }
  inline int finddelmax(Node *&p) {
    if (!(p->right)) {
      int ret = p->key;
      p = p->left;
      maintain(p);
      return ret;
    } else {
      int ret = finddelmax(p->right);
      maintain(p);
      return ret;
    }
  }
  inline void del(int ikey, Node *&p) {
    if (p->key == ikey) {
      if (!(p->left))
        p = p->right;
      else if (!(p->right))
        p = p->left;
      else
        p->key = finddelmax(p->left);
    } else if (ikey < p->key) {
      del(ikey, p->left);
    } else {
      del(ikey, p->right);
    }
    maintain(p);
  }
  inline void Del(int ikey) { del(ikey, root); }
  inline int qsum(int k, Node *&p) {
    if (p->size == k)
      return p->sum;
    else if (lsize(p) >= k)
      return qsum(k, p->left);
    else if (lsize(p) == k - 1)
      return lsum(p) + p->key;
    else
      return lsum(p) + p->key + qsum(k - lsize(p) - 1, p->right);
  }
  inline int Qsum(int k) { return qsum(k, root); }
} A;
vector<int> V[N];
int main() {
  ios::sync_with_stdio(false);
  int n;
  cin >> n;
  for (int i = 0; i < N; i++) V[i].clear();
  for (int i = 0; i < n; i++) {
    int a, b;
    cin >> a >> b;
    V[a].push_back(b);
    if (a) A.Insert(b);
  }
  set<pair<int, int> > S;
  S.clear();
  for (int i = 1; i < N; i++) {
    if (V[i].size()) {
      sort(V[i].begin(), V[i].end(), greater<int>());
      S.insert(make_pair(V[i].size(), i));
    }
  }
  int ans = 0x7f7f7f7f;
  int temp = 0;
  int myTicket = V[0].size();
  for (int i = 100001; i > 0; i--) {
    while (S.size() && S.rbegin()->first >= i) {
      pair<int, int> p = *S.rbegin();
      temp += V[p.second][V[p.second].size() - 1];
      myTicket++;
      A.Del(V[p.second][V[p.second].size() - 1]);
      V[p.second].pop_back();
      S.erase(p);
      p.first -= 1;
      S.insert(p);
    }
    if (myTicket >= i) {
      ans = min(ans, temp);
      break;
    } else if (A.root && A.root->size >= i - myTicket)
      ans = min(ans, temp + A.Qsum(i - myTicket));
  }
  cout << ans << '\n';
  return 0;
}
