#include <bits/stdc++.h>
using namespace std;
long long seg_tree[100000 * 4 + 9];
long long lazy[100000 * 4 + 9];
void init_tree(int node, int beg, int end) {
  if (beg == end) {
    seg_tree[node] = (-(1LL << 60));
    lazy[node] = (-(1LL << 60));
    return;
  }
  int mid = (beg + end) >> 1;
  init_tree((node << 1), beg, mid);
  init_tree((node << 1) | 1, mid + 1, end);
  seg_tree[node] = (-(1LL << 60));
  lazy[node] = (-(1LL << 60));
}
inline void split_node(int node) {
  if (lazy[node] == (-(1LL << 60))) return;
  seg_tree[(node << 1)] = lazy[node];
  lazy[(node << 1)] = lazy[node];
  seg_tree[(node << 1) | 1] = lazy[node];
  lazy[(node << 1) | 1] = lazy[node];
  lazy[node] = (-(1LL << 60));
}
inline void merge_node(int node) {
  seg_tree[node] = max(seg_tree[(node << 1)], seg_tree[(node << 1) | 1]);
}
void update(int node, int beg, int end, int i, int j, long long value) {
  if (beg > j || end < i) return;
  if (beg >= i && end <= j) {
    seg_tree[node] = value;
    lazy[node] = value;
    return;
  }
  split_node(node);
  int mid = (beg + end) >> 1;
  update((node << 1), beg, mid, i, j, value);
  update((node << 1) | 1, mid + 1, end, i, j, value);
  merge_node(node);
}
long long query_leftmost(int node, int beg, int end, int i, int j,
                         long long target) {
  if (i > end || j < beg) return (1 << 30);
  if (seg_tree[node] < target) return (1 << 30);
  if (beg == end) return beg;
  split_node(node);
  int mid = (beg + end) >> 1;
  int ind = query_leftmost((node << 1), beg, mid, i, j, target);
  if (ind != (1 << 30)) return ind;
  return query_leftmost(((node << 1) | 1), mid + 1, end, i, j, target);
}
long long query_rightmost(int node, int beg, int end, int i, int j,
                          long long target) {
  if (i > end || j < beg) return (-(1 << 30));
  if (seg_tree[node] < target) return (-(1 << 30));
  if (beg == end) return beg;
  split_node(node);
  int mid = (beg + end) >> 1;
  int ind = query_rightmost(((node << 1) | 1), mid + 1, end, i, j, target);
  if (ind != (-(1 << 30))) return ind;
  return query_rightmost((node << 1), beg, mid, i, j, target);
}
long long query(int node, int beg, int end, int i, int j) {
  if (i > end || j < beg) return (-(1LL << 60));
  if (beg >= i && end <= j) return seg_tree[node];
  split_node(node);
  int mid = (beg + end) >> 1;
  long long leftnode = query((node << 1), beg, mid, i, j);
  long long rightnode = query(((node << 1) | 1), mid + 1, end, i, j);
  return max(leftnode, rightnode);
}
void compress_vector(vector<long long> &uncompressed,
                     vector<long long> &compressed) {
  compressed.clear();
  sort(uncompressed.begin(), uncompressed.end());
  ;
  for (int i = 0; i < uncompressed.size(); i++) {
    if (i)
      if (uncompressed[i] == uncompressed[i - 1]) continue;
    compressed.push_back(uncompressed[i]);
  }
}
long long C[100000 + 9], S[100000 + 9];
vector<pair<long long, long long> > MAIN_VEC[100000 + 9], KEEP[100000 + 9];
map<long long, long long> mymap;
int main() {
  long long i, j, k, l, n, m, tot, curr, val, prev, a, b, c, t, cnt, x, y, siz,
      ii, jj, xx, yy, root, ind, len, q, xxx, yyy, d, r, no_per_blk;
  long long ans, temp;
  vector<long long> vec, comp_vec;
  cin >> n;
  for (i = 1; i <= n; i++) scanf("%lld%lld", &C[i], &S[i]);
  for (i = 1; i <= n; i++) vec.push_back(C[i]);
  compress_vector(vec, comp_vec);
  m = comp_vec.size();
  for (i = 0; i < m; i++) mymap[comp_vec[i]] = i + 1;
  for (i = 1; i <= n; i++) KEEP[mymap[C[i]]].push_back(make_pair(S[i], i));
  for (i = 1; i <= m; i++) KEEP[i].push_back(make_pair((-(1LL << 60)), 0));
  for (i = 1; i <= m; i++) sort(KEEP[i].begin(), KEEP[i].end());
  ;
  for (i = 1; i <= m; i++) reverse(KEEP[i].begin(), KEEP[i].end());
  ;
  for (i = 1; i <= n; i++)
    for (j = 0; j < KEEP[i].size(); j++)
      MAIN_VEC[j + 1].push_back(make_pair(i, KEEP[i][j].first));
  ans = (-(1LL << 60));
  init_tree(1, 1, n);
  for (i = 1; i <= n; i++) update(1, 1, n, i, i, 0);
  for (i = 1; i <= n; i++) {
    for (j = 0; j < MAIN_VEC[i].size(); j++) {
      curr = MAIN_VEC[i][j].first;
      temp = MAIN_VEC[i][j].second;
      val = query(1, 1, n, curr, curr);
      update(1, 1, n, curr, curr, 0);
      x = query(1, 1, n, 1, n);
      if (x > 0) {
        if (x + val + temp > ans) {
          ans = x + val + temp;
          a = curr;
          b = query_leftmost(1, 1, n, 1, n, x);
          xx = i;
          yy = i - 1;
        }
      }
      update(1, 1, n, curr, curr, val);
    }
    for (j = 0; j < MAIN_VEC[i].size(); j++) {
      curr = MAIN_VEC[i][j].first;
      temp = MAIN_VEC[i][j].second;
      val = query(1, 1, n, curr, curr);
      update(1, 1, n, curr, curr, val + temp);
    }
    if (MAIN_VEC[i].size() <= 0) continue;
    val = query(1, 1, n, 1, n);
    curr = query_leftmost(1, 1, n, 1, n, val);
    update(1, 1, n, curr, curr, -1);
    x = query(1, 1, n, 1, n);
    if (x > 0) {
      if (x + val > ans) {
        ans = x + val;
        a = curr;
        b = query_leftmost(1, 1, n, 1, n, x);
        xx = i;
        yy = i;
      }
    }
    update(1, 1, n, curr, curr, val);
  }
  cout << ans << endl;
  cout << xx + yy << endl;
  if (xx < yy) {
    swap(xx, yy);
    swap(a, b);
  }
  ii = 0;
  jj = 0;
  for (i = 0; i < xx + yy; i++) {
    if (i % 2 == 0)
      temp = KEEP[a][ii++].second;
    else
      temp = KEEP[b][jj++].second;
    printf("%lld ", temp);
  }
  cout << endl;
}
