import java.io.*;
import java.util.*;

public class elect_is2 implements Runnable {
    private static final String FILENAME = elect_is2.class.getName().substring(0, elect_is2.class.getName().indexOf('_'));
    
    private static final int inf = (int) 1e7;
    
    File inFile = new File(FILENAME + ".in");
    PrintWriter out;
    BufferedReader in;

    private StringTokenizer st;

	private long[] v;

	private int[] p;

	private Integer[] r;

	private int n;

    elect_is2() {     
        try {
            in = new BufferedReader(new FileReader(inFile));
            st = new StringTokenizer(in.readLine());
            out = new PrintWriter(new File(FILENAME + ".out"));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(239);           
        }       
    }
    
    int nextInt() throws IOException {
        if (!st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return Integer.parseInt(st.nextToken());
    }
    
    class C implements Comparator<Integer> {
        long[] v;
        int[] p;
        C(long[] v, int[] p) {
            this.v = v;
            this.p = p;
        }
        public int compare(Integer o1, Integer o2) {
            int t = Long.signum(v[o2] - v[o1]);
            return (t == 0) ? p[o2] - p[o1] : t;
        }
    }
    
    class ST {    	
		int[] o;
    	int N;
    	int[] d;
    	ST(int[] d) {
    		this.d = d;
    		N = 1;
    		while (N < d.length) {
    			N *= 2;
    		}
    		o = new int[2 * N];
    		for (int i = 2 * N - 1; i >= 1; i--) {
    			if (2 * i >= 2 * N) {    				
					o[i] = (i - N < d.length) ? d[i - N] : inf;
    			}
    			else {
    				o[i] = Math.min(o[2 * i], o[2 * i + 1]);
    			}
    		}
    	}
    	int get(int l, int r) {
    		l += N;
    		r += N;
    		int res = inf;
    		while (l < r) {
    			if (l % 2 == 1) {
    				res = Math.min(res, o[l]);
    				l++;
    			}
    			if (r % 2 == 0) {
    				res = Math.min(res, o[r]);
    				r--;
    			}
    			l /= 2;
    			r /= 2;
    		}
    		if (l <= r) {
    			res = Math.min(res, o[l]); 
    		}
    		return res; 
    	}
		public int findMin(int i, int j) {
			int imin = j;
			for (int k = i; k < j; k++) {
				if (d[imin] > d[k])
					imin = k;
			}
			return imin;
		}
    }
    
    private int advance(int fng, long level) {
    	while (fng < n && v[r[fng]] > level) 
    		fng++;
		return fng;
	}    
    
    public void run() {
        try {
            n = nextInt();
            int i;
            v = new long[n];
            p = new int[n];            
            for (i = 0; i < n; i++) {               
                v[i] = nextInt();
                p[i] = nextInt();
                if (p[i] == -1)
                	p[i] = inf;
            }
            r = new Integer[n];
            for (i = 0; i < n; i++)
                r[i] = i;
            Arrays.sort(r, new C(v, p));
            int[] dpv = new int[n];
            int[] dp = new int[n];
            long[] ps = new long[n + 1];
            
            for (i = 0; i < n; i++) {
				dpv[i] = (int) (p[r[i]] - v[r[i]]);
				dp[i] = (int) p[r[i]];
				ps[i] = (i == 0) ? 0 : ps[i - 1] + v[r[i - 1]];
			}
            ps[n] = v[r[n - 1]] + ps[n - 1];                        
            
            long res = Integer.MAX_VALUE;
            boolean resPart = false;
            int resRB = -1;
            long resLevel = -1;
            int resFNG = -1;
            
            ST stpv = new ST(dpv);
            ST stp = new ST(dp);
            
            int fng = 0;  //first that is not greater than level           
            for (long level = v[r[0]]; level >= 0; level--) {
//            	for (fng = advance(fng, level); ; fng++) {
            	{
        		fng = advance(fng, level);
//            		if (fng >= n || v[r[fng]] < level)
//            			break;
            	long r1 = ps[fng] - level * (fng - 1) + stpv.get(0, fng - 1);
            	
            	long minv = level * (fng + 1) + 1 - ps[fng];            	
            	
            	long r2;
            	int rb = -1;
            	if (minv > v[r[0]]) {
            		r2 = Long.MAX_VALUE;            		
            	} else {            		
            		{
            			int lb = 0;
            			rb = n;
            			while (lb + 1 < rb) {
            				int x = (lb + rb) / 2;
            				if (v[r[x]] >= minv)
            					lb = x;
            				else
            					rb = x;
            			}
            			rb = lb;
            		}
            		r2 = ps[fng] - level * fng + stp.get(fng, rb);            		
            	}
            	
            	long rm = Math.min(r1, r2);          	
            	if (res > rm) {
            		res = rm;
            		resLevel = level;
            		resRB = rb;
            		resPart = (rm == r1);
            		resFNG = fng;
            	}
        	}
            }
            
            fng = resFNG;            
            int resi = resPart 
            				? stpv.findMin(0, fng - 1) 
            				: stp.findMin(fng, resRB);
            resi = r[resi];
            
            out.println(res);
            out.println(resi + 1);
            if (p[resi] == -1) {
                throw new RuntimeException("Buying honest party");
            }
            long nres = p[resi];
            
            for (long rl : new long[]{resLevel + 1, resLevel}) {
                for (int j = 0; j < n; j++) {
                    if (r[j] == resi || v[r[j]] < v[resi] || v[r[j]] < rl)
                        continue;
                    v[resi] += v[r[j]] - rl;
                                    
                    nres += v[r[j]] - rl;
                    
                    v[r[j]] = rl;                         
                }
            }            
            
            if (nres != res) {
                throw new RuntimeException("Wrong money calc");
            }
            for (int j = 0; j < n; j++) {
                out.print(v[j] + " ");              
            }
            out.println();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            out.close();
        }
        
                
    } 

	public static void main(String[] args) {
        new Thread(new elect_is2()).start();
    }

}