using System;
using System.Collections.Generic;
using System.Globalization;
using System.Numerics;

public class Example
{
    public struct Din
    {
        public int value;
        public int number;
    }

    public class DinComparer : IComparer<Din>
    {
        public int Compare(Din x, Din y)
        {
            // Compare y and x in reverse order.
            return x.value.CompareTo(y.value);
        }
    }

    public static void Main()
    {

        string[] smas;

        smas = Console.ReadLine().Split(' ');
        int n = int.Parse(smas[0]);
        int v = int.Parse(smas[1]);

        //Din[] mm = new Din[200001];
        int max_pos = 1;
        int max_i = 0;
        Din[] m1 = new Din[100001];
        Din[] m2 = new Din[100001];
        int c1 = 0;
        int c2 = 0;

        for (int i = 0; i< n; i++)
        {
            smas = Console.ReadLine().Split(' ');
            int t = int.Parse(smas[0]);
            int p = int.Parse(smas[1]);
            var din = new Din() { value = p, number = i+1};
            if (t == 1)
            {
                m1[c1] = din;
                c1 ++;
            } else
            {
                m2[c2] = din;
                c2 ++;
            }
        }
        Array.Sort(m1, 0, c1, new DinComparer());
        Array.Sort(m2, 0, c2, new DinComparer());

        List<Din> result = new List<Din>();

        int tek1 = c1-1;
        int tek2 = c2-1;

        while (v > 0)
        {
            bool f = false;
            if (v % 2 == 1)
            {
                if (tek1 >= 0)
                {
                    result.Add(m1[tek1]);
                    tek1--;
                    f = true;
                    v--;
                }
            }
            else
            {
                if (tek2 >= 0)
                {
                    if (tek1 >= 1)
                    {
                        if (m2[tek2].value > m1[tek1].value + m1[tek1 - 1].value)
                        {
                            result.Add(m2[tek2]);
                            tek2--;
                            f = true;
                            v -= 2;
                        }
                        else
                        {
                            result.Add(m1[tek1]);
                            result.Add(m1[tek1 - 1]);
                            tek1 -= 2;
                            f = true;
                            v -= 2;
                        }
                    }
                    else if (tek1 == 0)
                    {
                        if (m2[tek2].value > m1[tek1].value)
                        {
                            result.Add(m2[tek2]);
                            tek2--;
                            f = true;
                            v -= 2;
                        }
                        else
                        {
                            result.Add(m1[tek1]);
                            tek1 -= 1;
                            f = true;
                            v -= 1;
                        }
                    }
                    else
                    {
                        result.Add(m2[tek2]);
                        tek2--;
                        f = true;
                        v -= 2;
                    }
                }
                else
                {
                    if (tek1 >= 1)
                    {
                        result.Add(m1[tek1]);
                        result.Add(m1[tek1 - 1]);
                        tek1 -= 2;
                        f = true;
                        v -= 2;
                    }
                    else if (tek1 == 0)
                    {
                        result.Add(m1[tek1]);
                        tek1 -= 1;
                        f = true;
                        v -= 1;
                    }
                }

            }

            if (!f) break;
        }

        int s = 0;
        foreach (var d in result)
        {
            s += d.value;
        }

        Console.WriteLine(s);
        foreach (var d in result)
        {
            Console.WriteLine(d.number);
        }

    }
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Globalization;

class Program
{
    public class Item : IComparable<Item>
    {
        public int V, P, Id;

        public int CompareTo(Item other)
        {
            return -(this.P * other.V).CompareTo(other.P * this.V);
        }
    }

    static void Main(string[] args)
    {
        int n = RI();
        int v = RI();
        Item[] m = new Item[n];
        for (int i = 0; i < n; i++)
            m[i] = new Item() { V = RI(), P = RI(), Id = i + 1 };
        Array.Sort(m);

        int lastOnePos = -1;

        List<Item> taken = new List<Item>();
        for (int i = 0; i < n; i++)
        {
            if (v <= 1)
            {
                if (v == 1)
                {
                    Item lastOne = null;
                    if (lastOnePos >= 0)
                        lastOne = taken[lastOnePos];

                    Item new1 = null;
                    Item new2 = null;
                    for (int j = i; j < n; j++)
                    {
                        if (new1 == null && m[j].V == 1) new1 = m[i];
                        if (new2 == null && m[j].V == 2) new2 = m[i];
                    }

                    if (lastOne == null)
                    {
                        if (new1 != null)
                            taken.Add(new1);
                    }
                    else
                    {
                        if (new1 != null && new2 == null)
                            taken.Add(new1);

                        if (new2 != null)
                        {
                            if (new1 == null)
                            {
                                if (lastOne.P < new2.P)
                                {
                                    taken[lastOnePos] = new2;
                                }
                            }
                            else
                            {
                                if (lastOne.P + new1.P >= new2.P)
                                {
                                    taken.Add(new1);
                                }
                                else
                                {
                                    taken[lastOnePos] = new2;
                                }
                            }
                        }
                    }
                }

                break;
            }

            v -= m[i].V;
            taken.Add(m[i]);
            if (m[i].V == 1)
                lastOnePos = taken.Count - 1;
        }

        Console.WriteLine(taken.Sum(t => t.P));
        Console.WriteLine(string.Join(" ", taken.Select(t => t.Id)));
    }

    private const int Mod = 1000000000 + 7;

    #region Data Read
    private static char ReadSign()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (ans == '+' || ans == '-' || ans == '?')
                return (char)ans;
        }
    }

    private static long GCD(long a, long b)
    {
        if (a % b == 0) return b;
        return GCD(b, a % b);
    }

    private static List<int>[] ReadGraph(int n, int m)
    {
        List<int>[] g = new List<int>[n];
        for (int i = 0; i < n; i++) g[i] = new List<int>();
        for (int i = 0; i < m; i++)
        {
            int a = RI();
            int b = RI();

            g[a].Add(b);
            g[b].Add(a);
        }

        return g;
    }

    private static int[,] ReadGraphAsMatrix(int n, int m)
    {
        int[,] matrix = new int[n + 1, n + 1];
        for (int i = 0; i < m; i++)
        {
            int a = RI();
            int b = RI();
            matrix[a, b] = matrix[b, a] = 1;
        }

        return matrix;
    }

    private static void Sort(ref int a, ref int b)
    {
        if (a > b) Swap(ref a, ref b);
    }

    private static void Swap(ref int a, ref int b)
    {
        int tmp = a;
        a = b;
        b = tmp;
    }

    private const int BufferSize = 1 << 16;
    private static StreamReader consoleReader;
    private static MemoryStream testData;

    private static int RI()
    {
        int ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static ulong RUL()
    {
        ulong ans = 0;
        int chr;
        do
        {
            chr = consoleReader.Read();
            if (chr == -1)
                return 0;
        } while (chr < '0' || chr > '9');

        ans = (uint)(chr - '0');
        while (true)
        {
            chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans;
            ans = ans * 10 + (uint)(chr - '0');
        }
    }

    private static long RL()
    {
        long ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static int[] RIA(int n)
    {
        int[] ans = new int[n];
        for (int i = 0; i < n; i++)
            ans[i] = RI();
        return ans;
    }

    private static long[] RLA(int n)
    {
        long[] ans = new long[n];
        for (int i = 0; i < n; i++)
            ans[i] = RL();
        return ans;
    }

    private static char[] ReadString()
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        List<char> s = new List<char>();
        do
        {
            s.Add((char)ans);
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s.ToArray();
    }

    private static char[] ReadString(int n)
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        char[] s = new char[n];
        int pos = 0;
        do
        {
            s[pos++] = (char)ans;
            if (pos == n) break;
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s;
    }

    private static char[] ReadStringLine()
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (ans == 10 || ans == 13);

        List<char> s = new List<char>();

        do
        {
            s.Add((char)ans);
            ans = consoleReader.Read();
        } while (ans != 10 && ans != 13);

        return s.ToArray();
    }

    private static char ReadLetter()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'))
                return (char)ans;
        }
    }
    private static char ReadNonLetter()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')))
                return (char)ans;
        }
    }

    private static char ReadDigit()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (ans >= '0' && ans <= '9')
                return (char)ans;
        }
    }

    private static int ReadDigitInt()
    {
        return ReadDigit() - (int)'0';
    }

    private static char ReadAnyChar()
    {
        return (char)consoleReader.Read();
    }

    private static string DoubleToString(double x)
    {
        return x.ToString(CultureInfo.InvariantCulture);
    }

    private static double DoubleFromString(string x)
    {
        return double.Parse(x, CultureInfo.InvariantCulture);
    }

    static Program()
    {
        //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        consoleReader = new StreamReader(Console.OpenStandardInput(BufferSize), Encoding.ASCII, false, BufferSize);
    }

    private static void PushTestData(StringBuilder sb)
    {
        PushTestData(sb.ToString());
    }
    private static void PushTestData(string data)
    {
#if TOLYAN_TEST
        if (testData == null)
        {
            testData = new MemoryStream();
            consoleReader = new StreamReader(testData);
        }

        var pos = testData.Position;
        var bytes = Encoding.UTF8.GetBytes(data);
        testData.Write(bytes, 0, bytes.Length);
        testData.Flush();
        testData.Position = pos;
#endif
    }
    #endregion
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Globalization;

class Program
{
    public class Item : IComparable<Item>
    {
        public int V, P, Id;

        public int CompareTo(Item other)
        {
            return -(this.P * other.V).CompareTo(other.P * this.V);
        }
    }

    static void Main(string[] args)
    {
        int n = RI();
        int v = RI();
        Item[] m = new Item[n];
        for (int i = 0; i < n; i++)
            m[i] = new Item() { V = RI(), P = RI(), Id = i + 1 };
        Array.Sort(m);

        int lastOnePos = -1;

        List<Item> taken = new List<Item>();
        for (int i = 0; i < n; i++)
        {
            if (v <= 1)
            {
                if (v == 1)
                {
                    Item lastOne = null;
                    if (lastOnePos >= 0)
                        lastOne = taken[lastOnePos];

                    Item new1 = null;
                    Item new2 = null;
                    for (int j = i; j < n; j++)
                    {
                        if (new1 == null && m[j].V == 1) new1 = m[j];
                        if (new2 == null && m[j].V == 2) new2 = m[j];
                    }

                    if (lastOne == null)
                    {
                        if (new1 != null)
                            taken.Add(new1);
                    }
                    else
                    {
                        if (new1 != null && new2 == null)
                            taken.Add(new1);

                        if (new2 != null)
                        {
                            if (new1 == null)
                            {
                                if (lastOne.P <= new2.P)
                                {
                                    taken[lastOnePos] = new2;
                                }
                            }
                            else
                            {
                                if (lastOne.P + new1.P >= new2.P)
                                {
                                    taken.Add(new1);
                                }
                                else
                                {
                                    taken[lastOnePos] = new2;
                                }
                            }
                        }
                    }
                }

                break;
            }

            v -= m[i].V;
            taken.Add(m[i]);
            if (m[i].V == 1)
                lastOnePos = taken.Count - 1;
        }

        Console.WriteLine(taken.Sum(t => t.P));
        Console.WriteLine(string.Join(" ", taken.Select(t => t.Id)));
    }

    private const int Mod = 1000000000 + 7;

    #region Data Read
    private static char ReadSign()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (ans == '+' || ans == '-' || ans == '?')
                return (char)ans;
        }
    }

    private static long GCD(long a, long b)
    {
        if (a % b == 0) return b;
        return GCD(b, a % b);
    }

    private static List<int>[] ReadGraph(int n, int m)
    {
        List<int>[] g = new List<int>[n];
        for (int i = 0; i < n; i++) g[i] = new List<int>();
        for (int i = 0; i < m; i++)
        {
            int a = RI();
            int b = RI();

            g[a].Add(b);
            g[b].Add(a);
        }

        return g;
    }

    private static int[,] ReadGraphAsMatrix(int n, int m)
    {
        int[,] matrix = new int[n + 1, n + 1];
        for (int i = 0; i < m; i++)
        {
            int a = RI();
            int b = RI();
            matrix[a, b] = matrix[b, a] = 1;
        }

        return matrix;
    }

    private static void Sort(ref int a, ref int b)
    {
        if (a > b) Swap(ref a, ref b);
    }

    private static void Swap(ref int a, ref int b)
    {
        int tmp = a;
        a = b;
        b = tmp;
    }

    private const int BufferSize = 1 << 16;
    private static StreamReader consoleReader;
    private static MemoryStream testData;

    private static int RI()
    {
        int ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static ulong RUL()
    {
        ulong ans = 0;
        int chr;
        do
        {
            chr = consoleReader.Read();
            if (chr == -1)
                return 0;
        } while (chr < '0' || chr > '9');

        ans = (uint)(chr - '0');
        while (true)
        {
            chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans;
            ans = ans * 10 + (uint)(chr - '0');
        }
    }

    private static long RL()
    {
        long ans = 0;
        int mul = 1;
        do
        {
            ans = consoleReader.Read();
            if (ans == -1)
                return 0;
            if (ans == '-') mul = -1;
        } while (ans < '0' || ans > '9');

        ans -= '0';
        while (true)
        {
            int chr = consoleReader.Read();
            if (chr < '0' || chr > '9')
                return ans * mul;
            ans = ans * 10 + chr - '0';
        }
    }

    private static int[] RIA(int n)
    {
        int[] ans = new int[n];
        for (int i = 0; i < n; i++)
            ans[i] = RI();
        return ans;
    }

    private static long[] RLA(int n)
    {
        long[] ans = new long[n];
        for (int i = 0; i < n; i++)
            ans[i] = RL();
        return ans;
    }

    private static char[] ReadString()
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        List<char> s = new List<char>();
        do
        {
            s.Add((char)ans);
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s.ToArray();
    }

    private static char[] ReadString(int n)
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')));

        char[] s = new char[n];
        int pos = 0;
        do
        {
            s[pos++] = (char)ans;
            if (pos == n) break;
            ans = consoleReader.Read();
        } while ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'));

        return s;
    }

    private static char[] ReadStringLine()
    {
        int ans;

        do
        {
            ans = consoleReader.Read();
        } while (ans == 10 || ans == 13);

        List<char> s = new List<char>();

        do
        {
            s.Add((char)ans);
            ans = consoleReader.Read();
        } while (ans != 10 && ans != 13);

        return s.ToArray();
    }

    private static char ReadLetter()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if ((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z'))
                return (char)ans;
        }
    }
    private static char ReadNonLetter()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (!((ans >= 'a' && ans <= 'z') || (ans >= 'A' && ans <= 'Z')))
                return (char)ans;
        }
    }

    private static char ReadDigit()
    {
        while (true)
        {
            int ans = consoleReader.Read();
            if (ans >= '0' && ans <= '9')
                return (char)ans;
        }
    }

    private static int ReadDigitInt()
    {
        return ReadDigit() - (int)'0';
    }

    private static char ReadAnyChar()
    {
        return (char)consoleReader.Read();
    }

    private static string DoubleToString(double x)
    {
        return x.ToString(CultureInfo.InvariantCulture);
    }

    private static double DoubleFromString(string x)
    {
        return double.Parse(x, CultureInfo.InvariantCulture);
    }

    static Program()
    {
        //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        consoleReader = new StreamReader(Console.OpenStandardInput(BufferSize), Encoding.ASCII, false, BufferSize);
    }

    private static void PushTestData(StringBuilder sb)
    {
        PushTestData(sb.ToString());
    }
    private static void PushTestData(string data)
    {
#if TOLYAN_TEST
        if (testData == null)
        {
            testData = new MemoryStream();
            consoleReader = new StreamReader(testData);
        }

        var pos = testData.Position;
        var bytes = Encoding.UTF8.GetBytes(data);
        testData.Write(bytes, 0, bytes.Length);
        testData.Flush();
        testData.Position = pos;
#endif
    }
    #endregion
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    m=min(n*2,m)
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in m downTo a){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,a)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].first);pos-=go[pos].second}
    printLine(ans.joinToString(" "))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    m=min(n*2,m)
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in a..m){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,a)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].first);pos-=go[pos].second}
    ans.reverse()
    printLine(ans.joinToString(" "))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    m=min(n*2,m)
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in a..m){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,2)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].first);pos-=go[pos].second}
    printLine(ans.joinToString(" "))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    m=min(n*2,m)
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in a..m){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,a)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].first);pos-=go[pos].second}
    printLine(ans.joinToString(" "))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in a..m){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,2)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].first);pos-=go[pos].second}
    printLine(ans.joinToString(" "))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in a..m){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,2)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].first);pos-=go[pos].second}
    printLine(ans.joinToString(""))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    m=min(n*2,m)
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in a..m){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,a)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].first);pos-=go[pos].second}
    ans.reverse()
    printLine(ans.joinToString(""))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

val inf=2e9.toInt()
fun main(){
    var (n,m)=readInts()
    var dp=Array(m+1){-inf};dp[0]=0
    var go=Array(m+1){Pair(0,0)}
    for(i in 1..n){
        var (a,b)=readInts()
        for(j in a..m){
            if(dp[j]<dp[j-a]+b){
                dp[j]=dp[j-a]+b
                go[j]=Pair(i,2)
            }
        }
    }
    var pos=0
    for(i in 1..m)if(dp[i]>dp[pos])pos=i
    printLine("${dp[pos]}")
    var ans=ArrayList<Int>()
    while(pos>0){ans.add(go[pos].second);pos-=go[pos].second}
    printLine(ans.joinToString(""))
    output()
}


import java.util.*
import java.math.*
import kotlin.math.*

fun readLn()=readLine()!!
fun readInt()=readLn().toInt()
fun readInts()=readLn().split(" ").map{it.toInt()}
fun readLong()=readLn().toLong()
fun readLongs()=readLn().split(" ").map{it.toLong()}

val out=mutableListOf<String>()
fun printLine(s:String){out.add(s)}
fun output(){println(out.joinToString("\n"))}

fun main(){
    var (n,m)=readInts()
    var ids=Array(2){ArrayList<Pair<Int,Int>>()}
    for(i in 1..n){
        var (a,b)=readInts()
        ids[a-1].add(Pair(b,i))
    }
    ids[0]=ArrayList(ids[0].sortedBy({-it.first}))
    ids[1]=ArrayList(ids[1].sortedBy({-it.first}))
    var sum=Array(2){Array(ids[it].size+1){0}}
    for(i in 0..1)for(j in 1..ids[i].size)sum[i][j]=sum[i][j-1]+ids[i][j-1].first
    var L=0;var R=0;var ans=0
    for(i in 0..ids[1].size){
        if(i*2>m)break
        var now=sum[1][i]+sum[0][min(ids[0].size,m-2*i)]
        if(now>ans){ans=now;L=i;R=min(ids[0].size,m-2*i)}
    }
    printLine("$ans")
    var lne=ArrayList<Int>()
    for(i in 0 until R)lne.add(ids[0][i].second)
    for(i in 0 until L)lne.add(ids[1][i].second)
    printLine(lne.joinToString(" "))
    output()
}


import java.util.*

class Vehicle(val volume: Int, val capacity: Int, val id: Int) : Comparable<Vehicle> {
    override fun compareTo(other: Vehicle): Int = other.capacity * this.volume - this.capacity * other.volume
}

fun main() {
    val scanner = Scanner(System.`in`)
    val n = scanner.nextInt()
    val v = scanner.nextInt()
    val vehicles = arrayListOf<Vehicle>()
    for (i in 0 until n) {
        val volume = scanner.nextInt()
        val capacity = scanner.nextInt()
        vehicles.add(Vehicle(volume, capacity, i + 1))
    }
    vehicles.sort()
    var ans = 0
    var remaining = v
    val kayaks = Stack<Int>()
    val catamarans = Stack<Int>()
    var firstUnchosenCatamaran = -1
    for (i in 0 until n) {
        if (vehicles[i].volume <= remaining) {
            remaining -= vehicles[i].volume
            ans += vehicles[i].capacity
            if (vehicles[i].volume == 1) {
                kayaks.push(i)
            } else {
                catamarans.push(i)
            }
        } else if (vehicles[i].volume == 2 && firstUnchosenCatamaran < 0) {
            firstUnchosenCatamaran = i
        }
    }

    if (firstUnchosenCatamaran >= 0) {
        if (remaining == 1) {
            val lastKayak = kayaks.peek()
            if (vehicles[firstUnchosenCatamaran].capacity > vehicles[lastKayak].capacity) {
                kayaks.pop()
                catamarans.push(firstUnchosenCatamaran)
                ans += vehicles[firstUnchosenCatamaran].capacity - vehicles[lastKayak].capacity
            }
        }

        if (remaining == 0 && kayaks.size >= 2) {
            val lastKayak = kayaks.pop()
            val secondLastKayak = kayaks.peek()
            val kayakCapcity = vehicles[lastKayak].capacity + vehicles[secondLastKayak].capacity
            if (vehicles[firstUnchosenCatamaran].capacity > kayakCapcity) {
                kayaks.pop()
                catamarans.push(firstUnchosenCatamaran)
                ans += vehicles[firstUnchosenCatamaran].capacity - kayakCapcity
            } else {
                kayaks.push(lastKayak)
            }
        }
    }

    println(ans)
    while (!kayaks.empty()) {
        println(vehicles[kayaks.pop()].id)
    }

    while (!catamarans.empty()) {
        println(vehicles[catamarans.pop()].id)
    }
}


import java.util.Scanner

class Vehicle(val volume: Int, val capacity: Int, val id: Int) : Comparable<Vehicle> {
    override fun compareTo(other: Vehicle): Int = other.capacity * this.volume - this.capacity * other.volume
}

fun main() {
    val scanner = Scanner(System.`in`)
    val n = scanner.nextInt()
    val v = scanner.nextInt()
    val vehicles = arrayListOf<Vehicle>()
    for (i in 0 until n) {
        val volume = scanner.nextInt()
        val capacity = scanner.nextInt()
        vehicles.add(Vehicle(volume, capacity, i + 1))
    }
    vehicles.sort()
    var ans = 0
    var remaining = v
    val choose = mutableSetOf<Int>()
    for (i in 0 until n) {
        if (vehicles[i].volume <= remaining) {
            remaining -= vehicles[i].volume
            ans += vehicles[i].capacity
            choose.add(i)
        }
        if (remaining == 0) break
    }

    if (remaining == 1) {
        var minKayakId = -1
        var minKayakCapacity = Int.MAX_VALUE
        for (i in choose) {
            if (vehicles[i].volume == 1 && vehicles[i].capacity < minKayakCapacity) {
                minKayakCapacity = vehicles[i].capacity
                minKayakId = i
            }
        }

        var maxCatamaranId = -1
        var maxCatamaranCapacity = Int.MIN_VALUE
        if (minKayakId != -1) {
            for (i in 0 until n) {
                if (!choose.contains(i) && vehicles[i].volume == 2 && vehicles[i].capacity > maxCatamaranCapacity) {
                    maxCatamaranCapacity = vehicles[i].capacity
                    maxCatamaranId = i
                }
            }
        }

        if (maxCatamaranCapacity > minKayakCapacity) {
            choose.remove(minKayakId)
            choose.add(maxCatamaranId)
            ans += maxCatamaranCapacity - minKayakCapacity
        }
    }

    println(ans)
    for (i in choose) {
        println(vehicles[i].id)
    }
}


import java.util.*

class Vehicle(val volume: Int, val capacity: Int, val id: Int) : Comparable<Vehicle> {
    override fun compareTo(other: Vehicle): Int = other.capacity * this.volume - this.capacity * other.volume
}

fun main() {
    val scanner = Scanner(System.`in`)
    val n = scanner.nextInt()
    val v = scanner.nextInt()
    val vehicles = arrayListOf<Vehicle>()
    for (i in 0 until n) {
        val volume = scanner.nextInt()
        val capacity = scanner.nextInt()
        vehicles.add(Vehicle(volume, capacity, i + 1))
    }
    vehicles.sort()
    var ans = 0
    var remaining = v
    val kayaks = Stack<Int>()
    val catamarans = Stack<Int>()
    var firstUnchosenCatamaran = -1
    for (i in 0 until n) {
        if (vehicles[i].volume <= remaining) {
            remaining -= vehicles[i].volume
            ans += vehicles[i].capacity
            if (vehicles[i].volume == 1) {
                kayaks.push(i)
            } else {
                catamarans.push(i)
            }
        } else if (vehicles[i].volume == 2 && firstUnchosenCatamaran < 0) {
            firstUnchosenCatamaran = i
        }
    }

    if (firstUnchosenCatamaran >= 0) {
        if (remaining == 1 && kayaks.size >= 1) {
            val lastKayak = kayaks.peek()
            if (vehicles[firstUnchosenCatamaran].capacity > vehicles[lastKayak].capacity) {
                kayaks.pop()
                catamarans.push(firstUnchosenCatamaran)
                ans += vehicles[firstUnchosenCatamaran].capacity - vehicles[lastKayak].capacity
            }
        }

        if (remaining == 0 && kayaks.size >= 2) {
            val lastKayak = kayaks.pop()
            val secondLastKayak = kayaks.peek()
            val kayakCapacity = vehicles[lastKayak].capacity + vehicles[secondLastKayak].capacity
            if (vehicles[firstUnchosenCatamaran].capacity > kayakCapacity) {
                kayaks.pop()
                catamarans.push(firstUnchosenCatamaran)
                ans += vehicles[firstUnchosenCatamaran].capacity - kayakCapacity
            } else {
                kayaks.push(lastKayak)
            }
        }
    }

    println(ans)
    while (!kayaks.empty()) {
        println(vehicles[kayaks.pop()].id)
    }

    while (!catamarans.empty()) {
        println(vehicles[catamarans.pop()].id)
    }
}


fun main(args: Array<String>) {
    main { readLine() }
}

fun main(readLine: () -> String?) {
    val problem = readProblem(readLine)
    val solution = solve(problem)
    printSolution(solution)
}

// READ PROBLEM

private fun readProblem(readLine: () -> String?): Problem {
    val (n, vol) = readNumbers(readLine)
    val vehicles = Array(n, {
        val (type, capacity) = readNumbers(readLine)
        Vehicle(it + 1, type, capacity)
    })
    return Problem(Lorry(vol), vehicles)
}

private fun readNumbers(readLine: () -> String?): Pair<Int, Int> {
    val line = readLine()!!
    val nums = line.trim().split(" ").take(2)
    return Pair(nums[0].toInt(), nums[1].toInt())
}

private data class Problem (val lorry: Lorry, val vehicles: Array<Vehicle>)

private data class Lorry(val volume: Int)

private class Vehicle(val no: Int, val type: Int, val capacity: Int) {
    override fun toString(): String {
        return "($no) $type - $capacity"
    }
}

// SOLVE PROBLEM

private fun solve(problem: Problem): Solution {
    problem.vehicles.sortBy { - it.capacity.toDouble() / it.type }

    val vehicles = problem.vehicles
    var volume = problem.lorry.volume
    var totalCapacity = 0
    var nextIndex = 0

    while (nextIndex < vehicles.size && volume >= vehicles[nextIndex].type) {
        val v = vehicles[nextIndex]
        volume -= v.type
        totalCapacity += v.capacity
        nextIndex += 1
    }

    if (volume > 0 && nextIndex < vehicles.size) {
        val lastSmall = find_last_small_vehicle_indx(vehicles, nextIndex)
        val nextBig = nextIndex
        val nextSmall = find_next_small_vehicle_indx(vehicles, nextIndex)

        if (lastSmall != null) {
            val capChange = vehicles[nextBig].capacity - vehicles[lastSmall].capacity
            if (nextSmall != null && vehicles[nextSmall].capacity > capChange) {
                // use the next small
                vehicles[nextIndex] = vehicles[nextSmall]
                totalCapacity += vehicles[nextSmall].capacity
                nextIndex += 1

            } else if (capChange > 0) {
                // replace last small with the next big
                vehicles[lastSmall] = vehicles[nextBig]
                totalCapacity += capChange
            }
        } else {
            if (nextSmall != null) {
                // use the next small
                vehicles[nextIndex] = vehicles[nextSmall]
                totalCapacity += vehicles[nextSmall].capacity
                nextIndex += 1
            }
        }
    }

    return Solution(totalCapacity, vehicles, nextIndex)
}

private fun find_last_small_vehicle_indx(vs: Array<Vehicle>, indx: Int): Int? {
    for (i in (indx - 1) downTo 0) {
        if (vs[i].type == 1) {
            return i
        }
    }
    return null
}

private fun find_next_small_vehicle_indx(vs: Array<Vehicle>, indx: Int): Int? {
    for (i in indx until vs.size) {
        if (vs[i].type == 1) {
            return i
        }
    }
    return null
}

// PRINT SOLUTION

private class Solution(
        val capacity: Int,
        val vehicles: Array<Vehicle>,
        val vehiclesNo: Int
) {
    fun print(consumer: (String) -> Unit) {
        consumer(capacity.toString())
        val sb = StringBuilder()
        for (i in 0 until vehiclesNo) {
            sb.append(vehicles[i].no.toString())
            sb.append(" ")
        }
        consumer(sb.toString())
    }
}

private fun printSolution(solution: Solution) {
    solution.print(::println)
}


fun main(args: Array<String>) {
    main { readLine() }
}

fun main(readLine: () -> String?) {
    val problem = readProblem(readLine)
    val solution = solve(problem)
    printSolution(solution)
}

// READ PROBLEM

fun readProblem(readLine: () -> String?): Problem {
    val (n, vol) = readNumbers(readLine)
    val vehicles = Array(n, {
        val (type, capacity) = readNumbers(readLine)
        Vehicle(it + 1, type, capacity)
    })
    return Problem(Lorry(vol), vehicles)
}

fun readNumbers(readLine: () -> String?): Pair<Int, Int> {
    val line = readLine()!!
    val nums = line.trim().split(" ").take(2)
    return Pair(nums[0].toInt(), nums[1].toInt())
}

data class Problem (val lorry: Lorry, val vehicles: Array<Vehicle>)

data class Lorry(val volume: Int)

data class Vehicle(val no: Int, val type: Int, val capacity: Int)

// SOLVE PROBLEM

fun solve(problem: Problem): Solution {
    problem.vehicles.sortBy { - it.capacity.toDouble() / it.type }
    val vehicles = problem.vehicles
    var volume = problem.lorry.volume
    var capacity = 0
    var nextIndex = 0

    while (nextIndex < vehicles.size && volume >= vehicles[nextIndex].type) {
        val v = vehicles[nextIndex]
        volume -= v.type
        capacity += v.capacity
        nextIndex += 1
    }

    if (volume > 0 && nextIndex < vehicles.size) {
        val lastSmall = find_last_small_vehicle_indx(vehicles, nextIndex)
        val nextBig = nextIndex
        val nextSmall = find_next_small_vehicle_indx(vehicles, nextIndex)

        if (lastSmall != null) {
            val capChange = vehicles[nextBig].capacity - vehicles[lastSmall].capacity
            if (nextSmall != null && vehicles[nextSmall].capacity > capChange) {
                // use the next small
                vehicles[nextIndex] = vehicles[nextSmall]
                nextIndex += 1
            } else if (capChange > 0) {
                // replace last small with the next big
                vehicles[lastSmall] = vehicles[nextBig]
            }
        } else {
            if (nextSmall != null) {
                // use the next small
                vehicles[nextIndex] = vehicles[nextSmall]
                nextIndex += 1
            }
        }
    }
    return Solution(capacity, vehicles, nextIndex)
}

fun find_last_small_vehicle_indx(vs: Array<Vehicle>, indx: Int): Int? {
    for (i in (indx - 1) downTo 0) {
        if (vs[i].type == 1) {
            return i
        }
    }
    return null
}

fun find_next_small_vehicle_indx(vs: Array<Vehicle>, indx: Int): Int? {
    for (i in indx until vs.size) {
        if (vs[i].type == 1) {
            return i
        }
    }
    return null
}

// PRINT SOLUTION

class Solution(
        val capacity: Int,
        val vehicles: Array<Vehicle>,
        val vehiclesNo: Int
) {
    fun print(consumer: (String) -> Unit) {
        consumer(capacity.toString())
        val sb = StringBuilder()
        for (i in 0 until vehiclesNo) {
            sb.append(vehicles[i].no.toString())
            sb.append(" ")
        }
        consumer(sb.toString())
    }
}

fun printSolution(solution: Solution) {
    solution.print(::println)
}


import java.util.*

/**
 * Created by AoEiuV020 on 2017/06/09-17:08:58.
 */
fun main(vararg args: String) {
    val (n, v) = readLine()!!.split(' ').map(String::toInt)
    var s = 0
    val l = LinkedList<Int>()
    val m = Array(n) {
        val (t, p) = readLine()!!.split(' ').map(String::toInt)
        arrayOf(t, p, it + 1)
    }.sortedByDescending {
        it[1].toDouble() / it[0]
    }.sumBy {
        if (s + it[0] <= v) {
            s += it[0]
            l.add(it[2])
            it[1]
        } else {
            0
        }
    }
    println(m)
    println(l.joinToString(" "))
}


import java.util.*

/**
 * Created by AoEiuV020 on 2017/06/09-17:08:58.
 */
fun main(vararg args: String) {
    val (n, v) = readLine()!!.split(' ').map(String::toInt)
    var s = 0
    val l = LinkedList<Int>()
    var last = arrayOf<Int>()
    val m = Array(n) {
        val (t, p) = readLine()!!.split(' ').map(String::toInt)
        arrayOf(t, p, it + 1)
    }.sortedByDescending {
        it[1].toDouble() / it[0]
    }.sumBy {
        if (s + it[0] <= v) {
            s += it[0]
            l.add(it[2])
            if(it[0] == 1) {
                last = it
            }
            it[1]
        } else if (it[0] == 2 && s == v - 1 && last[0] == 1 && it[1] >= last[1]) {
            System.err.println("$s, ${it[0]}, ${it[1]}, ${last}")
            s += 1
            l.remove(last[2])
            l.add(it[2])
            val t = last[1]
            last = it
            it[1] - t
        } else {
            0
        }
    }
    println(m)
    println(l.joinToString(" "))
}


import java.util.*

/**
 * 强行用贪心解01背包问题，
 * 代码相当混乱，
 * Created by AoEiuV020 on 2017/06/09-17:08:58.
 */
fun main(vararg args: String) {
    val (n, v) = readLine()!!.split(' ').map(String::toInt)
    var s = 0
    val l = LinkedList<Int>()
    var last = arrayOf<Int>(0, 0, 0)
    val m = Array(n) {
        val (t, p) = readLine()!!.split(' ').map(String::toInt)
        arrayOf(t, p, it + 1)
    }.sortedByDescending {
        it[1].toDouble() / it[0]
    }.sumBy {
        if (s + it[0] <= v) {
            s += it[0]
            l.add(it[2])
            if(it[0] == 1) {
                last = it
            }
            it[1]
        } else if (it[0] == 2 && s == v - 1 && last[0] == 1 && it[1] >= last[1]) {
            System.err.println("$s, ${it[0]}, ${it[1]}, ${last}")
            s += 1
            l.remove(last[2])
            l.add(it[2])
            val t = last[1]
            last = it
            it[1] - t
        } else {
            0
        }
    }
    println(m)
    println(l.joinToString(" "))
}


import java.util.*

/**
 * Created by AoEiuV020 on 2017/06/09-17:08:58.
 */
fun main(vararg args: String) {
    val (n, v) = readLine()!!.split(' ').map(String::toInt)
    var s = 0
    val m = Array(n) {
        readLine()!!.split(' ').map(String::toInt)
    }.sortedByDescending {
        it[1].toDouble() / it[0]
    }.sumBy {
        if (s + it[0] <= v) {
            s += it[0]
            it[1]
        } else {
            0
        }
    }
    println(m)
    println(s)
}


import java.util.*

/**
 * 强行用贪心解01背包问题，
 * 代码相当混乱，
 * Created by AoEiuV020 on 2017/06/09-17:08:58.
 */
fun main(vararg args: String) {
    val (n, v) = readLine()!!.split(' ').map(String::toInt)
    var s = 0
    val l = LinkedList<Int>()
    var last = arrayOf<Int>(0, 0, 0)
    val m = Array(n) {
        val (t, p) = readLine()!!.split(' ').map(String::toInt)
        arrayOf(t, p, it + 1)
    }.sortedByDescending {
        it[1].toDouble() / it[0]
    }.sumBy {
        if (s + it[0] <= v) {
            s += it[0]
            l.add(it[2])
            if(it[0] == 1) {
                last = it
            }
            it[1]
        } else if (it[0] == 2 && s == v - 1 && last[0] == 1 && it[1] >= last[1]) {
            System.err.println("$s, ${it[0]}, ${it[1]}, ${last}")
            s += 1
            l.remove(last[2])
            l.add(it[2])
            val t = last[1]
            last = it
            it[1] - t
        } else {
            0
        }
    }
    println(m)
    println(if (l.none()) 0 else l.joinToString(" "))
}


import java.util.*

/**
 * 强行用贪心解01背包问题，
 * 代码相当混乱，
 * Created by AoEiuV020 on 2017/06/09-17:08:58.
 */
fun main(vararg args: String) {
    val (n, v) = readLine()!!.split(' ').map(String::toInt)
    var s = 0
    val l = LinkedList<Int>()
    var last = arrayOf<Int>()
    val m = Array(n) {
        val (t, p) = readLine()!!.split(' ').map(String::toInt)
        arrayOf(t, p, it + 1)
    }.sortedByDescending {
        it[1].toDouble() / it[0]
    }.sumBy {
        if (s + it[0] <= v) {
            s += it[0]
            l.add(it[2])
            if(it[0] == 1) {
                last = it
            }
            it[1]
        } else if (it[0] == 2 && s == v - 1 && last[0] == 1 && it[1] >= last[1]) {
            System.err.println("$s, ${it[0]}, ${it[1]}, ${last}")
            s += 1
            l.remove(last[2])
            l.add(it[2])
            val t = last[1]
            last = it
            it[1] - t
        } else {
            0
        }
    }
    println(m)
    println(l.joinToString(" "))
}


import java.util.*

fun main() {
    val reader = Scanner(System.`in`)

    data class Vehicle(val number: Int, val capacity: Int, val type: Int)

    val n = reader.nextInt()
    var v = reader.nextInt()

    val kayaks = mutableListOf<Vehicle>()
    val catamarans = mutableListOf<Vehicle>()

    for (i in 1 .. n) {
        val type = reader.nextInt()
        val capacity = reader.nextInt()
        val vehicle = Vehicle(i, capacity, type)

        when (type) {
            1 -> kayaks.add(vehicle)
            2 -> catamarans.add(vehicle)
        }
    }

    kayaks.sortByDescending { it.capacity }
    catamarans.sortByDescending { it.capacity }

    var vehicle = mutableListOf<Vehicle>()

    var k = 0
    var c = 0

    fun hasNextKayak(): Boolean {
        return kayaks.size > k
    }

    fun hasNextCatamaran(): Boolean {
        return catamarans.size > c
    }

    fun getNextKayak() {
        v--
        vehicle.add(kayaks[k])
        k++
    }

    fun getNextCatamaran() {
        v -= 2
        vehicle.add(catamarans[c])
        c++
    }

    while (v > 0) {
        if (!hasNextKayak()) {
            if (!hasNextCatamaran() || v == 1) {
                break
            }
            getNextCatamaran()
        } else {
            when (v) {
                1 -> getNextKayak()
                else -> if (!hasNextCatamaran() || catamarans[c].capacity < kayaks[k].capacity + if (k + 1 == kayaks.size) 0 else kayaks[k + 1].capacity) {
                    getNextKayak()
                } else {
                    getNextCatamaran()
                }
            }
        }
    }

    println(vehicle.map { it.capacity }.sum())
    println(vehicle.map { it.number }.joinToString(" "))
}


#include <functional>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>

using namespace std;

const int kMaxN = 100000;
int n, v, ca, cb;
pair<int, int> a[kMaxN + 1], b[kMaxN + 1];
int sa[kMaxN + 1], sb[kMaxN + 1];

int main() {
    scanf("%d%d", &n, &v);
    for (int t, q, i = 1; i <= n; ++ i) {
        scanf("%d%d", &t, &q);
        if (t == 1)
            a[++ ca] = make_pair(q, i);
        else
            b[++ cb] = make_pair(q, i);
    }
    sort(a + 1, a + ca + 1, greater<pair<int, int>>());
    sort(b + 1, b + cb + 1, greater<pair<int, int>>());
    for (int i = 1; i <= ca; ++ i) sa[i] = sa[i - 1] + a[i].first;
    for (int i = 1; i <= cb; ++ i) sb[i] = sb[i - 1] + b[i].first;
    int ans = 0, _i, _j;
    for (int i = 0; i <= ca && i <= v; ++ i) {
        int j = (v - i) >> 1;
        if (sa[i] + sb[j] > ans) {
            ans = sa[i] + sb[j];
            _i = i, _j = j;
        }
    }
    printf("%d\n", ans);
    for (int i = 1; i <= _i; ++ i) printf("%d ", a[i].second);
    for (int i = 1; i <= _j; ++ i) printf("%d ", b[i].second);
    puts("");
    return 0;
}


#include <functional>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>

using namespace std;

const int kMaxN = 100000;
int n, v, ca, cb;
pair<int, int> a[kMaxN + 1], b[kMaxN + 1];
int sa[kMaxN + 1], sb[kMaxN + 1];

int main() {
    scanf("%d%d", &n, &v);
    for (int t, q, i = 1; i <= n; ++ i) {
        scanf("%d%d", &t, &q);
        if (t == 1)
            a[++ ca] = make_pair(q, i);
        else
            b[++ cb] = make_pair(q, i);
    }
    sort(a + 1, a + ca + 1, greater<pair<int, int>>());
    sort(b + 1, b + cb + 1, greater<pair<int, int>>());
    for (int i = 1; i <= ca; ++ i) sa[i] = sa[i - 1] + a[i].first;
    for (int i = 1; i <= cb; ++ i) sb[i] = sb[i - 1] + b[i].first;
    int ans = 0, _i = 0, _j = 0;
    for (int i = 0; i <= ca && i <= v; ++ i) {
        int j = min((v - i) >> 1, cb);
        if (sa[i] + sb[j] > ans) {
            ans = sa[i] + sb[j];
            _i = i, _j = j;
        }
    }
    printf("%d\n", ans);
    for (int i = 1; i <= _i; ++ i) printf("%d ", a[i].second);
    for (int i = 1; i <= _j; ++ i) printf("%d ", b[i].second);
    puts("");
    return 0;
}


#include <functional>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <utility>

using namespace std;

const int kMaxN = 100000;
int n, v, ca, cb;
pair<int, int> a[kMaxN + 1], b[kMaxN + 1];
int sa[kMaxN + 1], sb[kMaxN + 1];

int main() {
    scanf("%d%d", &n, &v);
    for (int t, q, i = 1; i <= n; ++ i) {
        scanf("%d%d", &t, &q);
        if (t == 1)
            a[++ ca] = make_pair(q, i);
        else
            b[++ cb] = make_pair(q, i);
    }
    sort(a + 1, a + ca + 1, greater<pair<int, int>>());
    sort(b + 1, b + cb + 1, greater<pair<int, int>>());
    for (int i = 1; i <= ca; ++ i) sa[i] = sa[i - 1] + a[i].first;
    for (int i = 1; i <= cb; ++ i) sb[i] = sb[i - 1] + b[i].first;
    int ans = 0, _i, _j;
    for (int i = 0; i <= ca && i <= v; ++ i) {
        int j = min((v - i) >> 1, cb);
        if (sa[i] + sb[j] > ans) {
            ans = sa[i] + sb[j];
            _i = i, _j = j;
        }
    }
    printf("%d\n", ans);
    for (int i = 1; i <= _i; ++ i) printf("%d ", a[i].second);
    for (int i = 1; i <= _j; ++ i) printf("%d ", b[i].second);
    puts("");
    return 0;
}


#include <bits/stdc++.h>

typedef int CraftType;

struct Craft
{
	int num;
	CraftType type;
	int payload;
	int worth;
	bool loaded;

	Craft(int num_, CraftType type_, int payload_, int worth_)
		: num(num_), type(type_), payload(payload_), worth(worth_), loaded(false)
	{}

	bool IsKayak() const {return type == 1;}
	bool IsCatamaran() const {return type == 2;}
};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
	{
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

		return true;
	}

	return lft.worth > rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for(int i = 1; i<= num_crafts; i++)
	{
		int type, payload;
		std::cin >> type >> payload;
		int worth = type == 1 ? 2*payload : payload;

		crafts.push_back
		({
			i,
			type,
			payload,
			worth
		});
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	for (auto& craft : crafts)
	{
		if (slots + craft.type > truck_slots)
			continue;

		craft.loaded = true;
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	if (slots != truck_slots) //1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	{
		for (auto kayak = crafts.rbegin(); kayak != crafts.rend(); ++kayak)
		{
			if (kayak->IsKayak() && kayak->loaded) //find kayak with min worth (due to sorting)
			{
				for (auto catamaran = crafts.begin(); catamaran != crafts.end(); ++catamaran)
				{
					if (catamaran->IsCatamaran() && !catamaran->loaded) //find not loaded catamaran with max worth (due to sorting)
					{
						kayak->loaded = false;
						catamaran->loaded = true;
						break;
					}
				}
				break;
			}
		}

	}

	unsigned max_volume = 0;
	for (auto& craft : crafts)
		if (craft.loaded)
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;

	for (auto& craft : crafts)
		if (craft.loaded)
			std::cout << craft.num << ' ';
	std::cout << std::endl;

	return 0;
}


#include <bits/stdc++.h>

typedef unsigned CraftType;

class Craft
{
private:
	bool loaded;
public:
	unsigned num;
	CraftType type;
	unsigned payload;
	unsigned worth;

	Craft(unsigned num_, CraftType type_, unsigned payload_):
		num(num_),
		type(type_),
		payload(payload_),
		worth(payload_),
		loaded(false)
	{
		if  (type == 1)
			worth = 2 * payload;
	}
	void Load(){ loaded = true;}
	void Unload(){loaded = false;}
	bool IsLoaded() const {return loaded; }
	bool IsKayak() const { return type == 1; }
	bool IsCatamaran() const { return type == 2; }

};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.num == rgt.num) //strict weak order
		return false;

	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for (unsigned i = 1u; i<= num_crafts; i++)
	{
		unsigned type, payload;
		std::cin >> type >> payload;
		Craft craft {i, type, payload};

		crafts.push_back(craft);
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0u;
	for(auto& craft : crafts)
	{
		if ((slots + craft.type) > truck_slots)
			continue;

		craft.Load();
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	//1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	if (slots != truck_slots)
	{
		for (size_t i = crafts.size(); i-->0 ;)
		{
			//find kayak with min worth (due to sorting)
			if (crafts[i].IsKayak() && crafts[i].IsLoaded())
			{
				for (size_t j = 0; j < crafts.size(); j++)
				{
					//find not loaded catamaran with max worth (due to sorting)
					if (crafts[j].IsCatamaran() && !(crafts[j].IsLoaded()))
					{
						crafts[i].Unload();
						crafts[j].Load();
						break;
					}
				}
				break;
			}
		}
	}

	unsigned max_volume = 0;
	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;

	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			std::cout << craft.num << ' ';
	std::cout << std::endl;

	return 0;
}


#include <bits/stdc++.h>

typedef unsigned CraftType;

struct Craft
{
	unsigned num;
	CraftType type;
	unsigned payload;
	unsigned worth;
	bool loaded;

	Craft(unsigned num_, CraftType type_, unsigned payload_):
		num(num_),
		type(type_),
		payload(payload_),
		worth(payload_),
		loaded(false)
	{
		if  (type == 1)
			worth = 2 * payload;
	}

	bool IsKayak() const { return type == 1; }
	bool IsCatamaran() const { return type == 2; }
};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for (unsigned i = 1; i<= num_crafts; i++)
	{
		unsigned type, payload;
		std::cin >> type >> payload;
		crafts.emplace_back(Craft(i, type, payload));
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	for(auto& craft : crafts)
	{
		if (slots + craft.type > truck_slots)
			continue;

		craft.loaded = true;
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	//1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	if (slots != truck_slots)
	{
		for (size_t i = crafts.size(); i >= 0; --i)
		{
			//find kayak with min worth (due to sorting)
			if (crafts[i].IsKayak() && crafts[i].loaded)
			{
				for (unsigned j = 0; j < crafts.size(); j++)
				{
					//find not loaded catamaran with max worth (due to sorting)
					if (crafts[j].IsCatamaran() && !(crafts[j].loaded))
					{
						crafts[i].loaded = false;
						crafts[j].loaded = true;
						break;
					}
				}
				break;
			}
		}
	}

	unsigned max_volume = 0;
	for (const auto& craft : crafts)
		if (craft.loaded)
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;

	for (const auto& craft : crafts)
		if (craft.loaded)
			std::cout << craft.num << ' ';

	return 0;
}


#include <bits/stdc++.h>

typedef int CraftType;

const unsigned max_payload = 10000;
constexpr unsigned max_worth() {return max_payload * 2;}

struct Craft
{
	int num;
	CraftType type;
	int payload;
	int worth;
	bool loaded;

	Craft(int num_, CraftType type_, int payload_, int worth_)
		: num(num_), type(type_), payload(payload_), worth(worth_), loaded(false)
	{}

	bool IsKayak() 	{return type == 1;}
	bool IsCatamaran() 	{return type == 2;}
};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		return lft.num < rgt.num;

	return lft.worth > rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for(int i = 1; i<= num_crafts; i++)
	{
		int type, payload;
		std::cin >> type >> payload;
		int worth = type == 1 ? 2*payload : payload;

		crafts.push_back
		({
			i,
			type,
			payload,
			worth
		});
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	for (auto& craft : crafts)
	{
		if (slots + craft.type > truck_slots)
			continue;

		craft.loaded = true;
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	if (slots != truck_slots) //1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	{
		for (auto kayak = crafts.rbegin(); kayak != crafts.rend(); ++kayak)
		{
			if (kayak->IsKayak() && kayak->loaded) //find kayak with min worth (due to sorting)
			{
				for (auto catamaran = crafts.begin(); catamaran != crafts.end(); ++catamaran)
				{
					if (catamaran->IsCatamaran() && !catamaran->loaded) //find not loaded catamaran with max worth (due to sorting)
					{
						kayak->loaded = false;
						catamaran->loaded = true;
						break;
					}
				}
				break;
			}
		}

	}

	unsigned max_volume = 0;
	for (auto& craft : crafts)
		if (craft.loaded)
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;
	for (auto& craft : crafts)
		if (craft.loaded)
			std::cout << craft.num << std::endl;

	return 0;
}

//6 1 9 2 4 7 - correct
//6 1 8 2 4 7- wrong


#include <bits/stdc++.h>

typedef unsigned CraftType;

class Craft
{
private:
	bool loaded;
public:
	unsigned num;
	CraftType type;
	unsigned payload;
	unsigned worth;

	Craft(unsigned num_, CraftType type_, unsigned payload_):
		num(num_),
		type(type_),
		payload(payload_),
		worth(payload_),
		loaded(false)
	{
		if  (type == 1)
			worth = 2 * payload;
	}
	void Load(){ loaded = true;}
	void Unload(){loaded = false;}
	bool IsLoaded() const {return loaded; }
	bool IsKayak() const { return type == 1; }
	bool IsCatamaran() const { return type == 2; }

};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	//freopen("test_case.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	bool alg_error = false;
	std::vector<Craft> input;
	unsigned num_crafts, truck_slots;
	unsigned n = 0;
	std::srand(time(nullptr));
//	while (!alg_error)
	{
	std::cin >> num_crafts >> truck_slots;

	input.clear();
	n++;
	//num_crafts = (unsigned)rand()%10000 +1;
	//std::cout << n << " " << num_crafts << ' ';

	//truck_slots = (unsigned)rand()%1000000000 + 1;

	std::vector<Craft> crafts;
	//crafts.reserve(num_crafts);
	for (unsigned i = 1; i<= num_crafts; i++)
	{
		unsigned type, payload;
		std::cin >> type >> payload;
		//type = (unsigned)rand()%2 +1;
		//payload = (unsigned)rand()%10000+1;
		Craft craft {i, type, payload};

		crafts.push_back(craft);
	}

	input = crafts;

	//solve
	// std::cout << "sort ";
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	// std::cout << "solve ";
	for(auto& craft : crafts)
	{

		if (slots + craft.type > truck_slots)
			continue;

		craft.Load();
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	//1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	if (slots != truck_slots)
	{
		// std::cout << "swap ";
		for (size_t i = crafts.size(); i > 0; --i)
		{
			//find kayak with min worth (due to sorting)
			if (crafts[i].IsKayak() && crafts[i].IsLoaded())
			{
				for (unsigned j = 0; j < crafts.size(); j++)
				{
					//find not loaded catamaran with max worth (due to sorting)
					if (crafts[j].IsCatamaran() && !(crafts[j].IsLoaded()))
					{
						crafts[i].Unload();
						crafts[j].Load();
						break;
					}
				}
				break;
			}
		}
	}

	unsigned max_volume = 0;
	// std::cout << "calc ";
	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			max_volume += craft.payload;

	//output
	//std::cout << "verify " << '\n';
	//for (const auto& craft : crafts)
	//	if (craft.num > num_crafts)
	//		alg_error = true;

	std::cout << max_volume << std::endl;

	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			std::cout << craft.num << ' ';
	std::cout << std::endl;
	}

	//std::cout << "write testcase " << '\n';

	// std::cout << num_crafts << " " << truck_slots << std::endl;
	// for(auto& craft: input)
	// {
	// 	std::cout<< craft.type << " " << craft.payload << '\n';
	// }
	// std::cout << std::endl;

	return 0;
}


#include <bits/stdc++.h>

typedef int CraftType;

struct Craft
{
	int num;
	CraftType type;
	int payload;
	int worth;

	Craft(int num_, CraftType type_, int payload_, int worth_)
		: num(num_), type(type_), payload(payload_), worth(worth_)
	{}
};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		return lft.num < rgt.num;

	return lft.worth > rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for(int i = 1; i<= num_crafts; i++)
	{
		int type, payload;
		std::cin >> type >> payload;
		int worth = type == 1 ? 2*payload : payload;

		crafts.push_back
		({
			i,
			type,
			payload,
			worth
		});
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0, volume = 0;
	std::vector<int> loaded_crafts;
	loaded_crafts.reserve(num_crafts);
	for (const auto& craft : crafts)
	{
		if (slots + craft.type <= truck_slots)
		{
			loaded_crafts.push_back(craft.num);
			slots += craft.type;
			volume += craft.payload;

			if (slots == truck_slots)
				break;
		}
	}

	//output
	std::cout << volume << std::endl;
	for (auto num : loaded_crafts)
		std::cout << num << std::endl;

	return 0;
}


#include <bits/stdc++.h>

typedef int CraftType;

struct Craft
{
	int num;
	CraftType type;
	int payload;
	int worth;
	bool loaded;

	Craft(int num_, CraftType type_, int payload_, int worth_)
		: num(num_), type(type_), payload(payload_), worth(worth_), loaded(false)
	{}

	bool IsKayak() const {return type == 1;}
	bool IsCatamaran() const {return type == 2;}
};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for(int i = 1; i<= num_crafts; i++)
	{
		int type, payload;
		std::cin >> type >> payload;
		int worth = type == 1 ? 2*payload : payload;

		crafts.push_back
		({
			i,
			type,
			payload,
			worth
		});
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	for (auto& craft : crafts)
	{
		if (slots + craft.type > truck_slots)
			continue;

		craft.loaded = true;
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	if (slots != truck_slots) //1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	{
		for (auto kayak = crafts.rbegin(); kayak != crafts.rend(); ++kayak)
		{
			if (kayak->IsKayak() && kayak->loaded) //find kayak with min worth (due to sorting)
			{
				for (auto catamaran = crafts.begin(); catamaran != crafts.end(); ++catamaran)
				{
					if (catamaran->IsCatamaran() && !catamaran->loaded) //find not loaded catamaran with max worth (due to sorting)
					{
						kayak->loaded = false;
						catamaran->loaded = true;
						break;
					}
				}
				break;
			}
		}

	}

	unsigned max_volume = 0;
	for (auto& craft : crafts)
		if (craft.loaded)
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;

	for (auto& craft : crafts)
		if (craft.loaded)
			std::cout << craft.num << " ";
	std::cout << std::endl;

	return 0;
}


#include <bits/stdc++.h>

typedef unsigned CraftType;

class Craft
{
private:
	bool loaded;
public:
	unsigned num;
	CraftType type;
	unsigned payload;
	unsigned worth;

	Craft(unsigned num_, CraftType type_, unsigned payload_):
		num(num_),
		type(type_),
		payload(payload_),
		worth(payload_),
		loaded(false)
	{
		if  (type == 1)
			worth = 2 * payload;
	}
	void Load(){ loaded = true;}
	void Unload(){loaded = false;}
	bool IsLoaded() const {return loaded; }
	bool IsKayak() const { return type == 1; }
	bool IsCatamaran() const { return type == 2; }

};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for (unsigned i = 1; i<= num_crafts; i++)
	{
		unsigned type, payload;
		std::cin >> type >> payload;
		Craft craft {i, type, payload};

		crafts.push_back(craft);
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	for(auto& craft : crafts)
	{
		if (slots + craft.type > truck_slots)
			continue;

		craft.Load();
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	//1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	if (slots != truck_slots)
	{
		for (size_t i = crafts.size(); i > 0; --i)
		{
			//find kayak with min worth (due to sorting)
			if (crafts[i].IsKayak() && crafts[i].IsLoaded())
			{
				for (unsigned j = 0; j < crafts.size(); j++)
				{
					//find not loaded catamaran with max worth (due to sorting)
					if (crafts[j].IsCatamaran() && !(crafts[j].IsLoaded()))
					{
						crafts[i].Unload();
						crafts[j].Load();
						break;
					}
				}
				break;
			}
		}
	}

	unsigned max_volume = 0;
	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;

	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			std::cout << craft.num << ' ';
	std::cout << std::endl;

	return 0;
}


#include <bits/stdc++.h>

typedef unsigned CraftType;

class Craft
{
private:
	bool loaded;
public:
	unsigned num;
	CraftType type;
	unsigned payload;
	unsigned worth;

	Craft(unsigned num_, CraftType type_, unsigned payload_):
		num(num_),
		type(type_),
		payload(payload_),
		worth(payload_),
		loaded(false)
	{
		if  (type == 1)
			worth = 2 * payload;
	}
	void Load(){ loaded = true;}
	void Unload(){loaded = false;}
	bool IsLoaded() const {return loaded; }
	bool IsKayak() const { return type == 1; }
	bool IsCatamaran() const { return type == 2; }

};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	freopen("test_case.txt", "r", stdin);
	freopen("output.txt", "w", stdout);

	bool alg_error = false;
	std::vector<Craft> input;
	unsigned num_crafts, truck_slots;
	unsigned n = 0;
	std::srand(time(nullptr));
//	while (!alg_error)
	{
	std::cin >> num_crafts >> truck_slots;

	input.clear();
	n++;
	//num_crafts = (unsigned)rand()%10000 +1;
	//std::cout << n << " " << num_crafts << ' ';

	//truck_slots = (unsigned)rand()%1000000000 + 1;

	std::vector<Craft> crafts;
	//crafts.reserve(num_crafts);
	for (unsigned i = 1; i<= num_crafts; i++)
	{
		unsigned type, payload;
		std::cin >> type >> payload;
		//type = (unsigned)rand()%2 +1;
		//payload = (unsigned)rand()%10000+1;
		Craft craft {i, type, payload};

		crafts.push_back(craft);
	}

	input = crafts;

	//solve
	// std::cout << "sort ";
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	// std::cout << "solve ";
	for(auto& craft : crafts)
	{

		if (slots + craft.type > truck_slots)
			continue;

		craft.Load();
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	//1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	if (slots != truck_slots)
	{
		// std::cout << "swap ";
		for (size_t i = crafts.size(); i > 0; --i)
		{
			//find kayak with min worth (due to sorting)
			if (crafts[i].IsKayak() && crafts[i].IsLoaded())
			{
				for (unsigned j = 0; j < crafts.size(); j++)
				{
					//find not loaded catamaran with max worth (due to sorting)
					if (crafts[j].IsCatamaran() && !(crafts[j].IsLoaded()))
					{
						crafts[i].Unload();
						crafts[j].Load();
						break;
					}
				}
				break;
			}
		}
	}

	unsigned max_volume = 0;
	// std::cout << "calc ";
	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			max_volume += craft.payload;

	//output
	//std::cout << "verify " << '\n';
	//for (const auto& craft : crafts)
	//	if (craft.num > num_crafts)
	//		alg_error = true;

	std::cout << max_volume << std::endl;

	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			std::cout << craft.num << ' ';
	std::cout << std::endl;
	}

	//std::cout << "write testcase " << '\n';

	// std::cout << num_crafts << " " << truck_slots << std::endl;
	// for(auto& craft: input)
	// {
	// 	std::cout<< craft.type << " " << craft.payload << '\n';
	// }
	// std::cout << std::endl;

	return 0;
}


#include <bits/stdc++.h>

typedef unsigned CraftType;

struct Craft
{
	unsigned num;
	CraftType type;
	unsigned payload;
	unsigned worth;
	bool loaded;

	Craft(unsigned num_, CraftType type_, unsigned payload_):
		num(num_),
		type(type_),
		payload(payload_),
		worth(payload_),
		loaded(false)
	{
		if  (type == 1)
			worth = 2 * payload;
	}

	bool IsKayak() const { return type == 1; }
	bool IsCatamaran() const { return type == 2; }
};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for (unsigned i = 1; i<= num_crafts; i++)
	{
		unsigned type, payload;
		std::cin >> type >> payload;
		crafts.emplace_back(Craft(i, type, payload));
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0;
	for(auto& craft : crafts)
	{
		if (slots + craft.type > truck_slots)
			continue;

		craft.loaded = true;
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	//1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	if (slots != truck_slots)
	{
		for (auto kayak = crafts.rbegin(); kayak != crafts.rend(); ++kayak)
		{
			//find kayak with min worth (due to sorting)
			if (kayak->IsKayak() && kayak->loaded)
			{
				for (auto& catamaran : crafts)
				{
					//find not loaded catamaran with max worth (due to sorting)
					if (catamaran.IsCatamaran() && !catamaran.loaded)
					{
						kayak->loaded = false;
						catamaran.loaded = true;
						break;
					}
				}
				break;
			}
		}
	}

	unsigned max_volume = 0;
	for (const auto& craft : crafts)
		if (craft.loaded)
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;

	for (const auto& craft : crafts)
		if (craft.loaded)
			std::cout << craft.num << ' ';

	return 0;
}


#include <bits/stdc++.h>

typedef unsigned CraftType;

class Craft
{
public:
	Craft(unsigned num_, CraftType type_, unsigned payload_):
		num(num_),
		type(type_),
		payload(payload_),
		worth(payload_),
		loaded(false)
	{
		if  (type == 1)
			worth = 2 * payload;
	}
	void Load(){ loaded = true;}
	void Unload(){loaded = false;}
	bool IsLoaded() const {return loaded; }
	bool IsKayak() const { return type == 1; }
	bool IsCatamaran() const { return type == 2; }

	unsigned num;
	CraftType type;
	unsigned payload;
	unsigned worth;
private:
	bool loaded;
};

bool craft_worth_cmp(const Craft& lft, const Craft& rgt)
{
	if (lft.num == rgt.num) //strict weak order
		return false;

	if (lft.worth == rgt.worth)
		if (lft.IsKayak() && rgt.IsCatamaran()) //catamarans should be first
			return false;

	return lft.worth >= rgt.worth;
}

int main()
{
	//io optimization
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);

	//input
	unsigned num_crafts, truck_slots;
	std::cin >> num_crafts >> truck_slots;

	std::vector<Craft> crafts;
	crafts.reserve(num_crafts);
	for (unsigned i = 1u; i<= num_crafts; i++)
	{
		unsigned type, payload;
		std::cin >> type >> payload;
		Craft craft {i, type, payload};

		crafts.push_back(craft);
	}

	//solve
	std::sort(crafts.begin(), crafts.end(), craft_worth_cmp);

	unsigned slots =0u;
	for(auto& craft : crafts)
	{
		if ((slots + craft.type) > truck_slots)
			continue;

		craft.Load();
		slots += craft.type;

		if (slots == truck_slots)
			break;
	}

	//1 slot is empty, we can remove 1 kayak and try find catamaran with more worth
	if (slots != truck_slots)
	{
		for (size_t i = crafts.size(); i-->0 ;)
		{
			//find kayak with min worth (due to sorting)
			if (crafts[i].IsKayak() && crafts[i].IsLoaded())
			{
				for (size_t j = 0; j < crafts.size(); j++)
				{
					//find not loaded catamaran with max worth (due to sorting)
					if (crafts[j].IsCatamaran() && !(crafts[j].IsLoaded()))
					{
						crafts[i].Unload();
						crafts[j].Load();
						break;
					}
				}
				break;
			}
		}
	}

	unsigned max_volume = 0;
	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			max_volume += craft.payload;

	//output
	std::cout << max_volume << std::endl;

	for (const auto& craft : crafts)
		if (craft.IsLoaded())
			std::cout << craft.num << ' ';
	std::cout << std::endl;

	return 0;
}


#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <math.h>
using namespace std;
#define LL long long

int main()
{
    int n, v;
    cin >> n >> v;
    vector<vector<double> > a(n, vector<double>(3));
    for (int i = 0; i < n; ++i)
    {
        int t, p;
        cin >> t >> p;
        a[i][1] = t;
        a[i][0] = 1.0 * p / t;
        a[i][2] = i + 1;
    }
    sort(a.begin(), a.end());
    reverse(a.begin(), a.end());
    vector<int> res;
    int cap = 0;
    int last1 = -1, first2 = -1;
    for (int i = 0; i < n; ++i)
    {
        if (v >= a[i][1])
        {
            v -= a[i][1];
            cap += a[i][0] * a[i][1];
            res.push_back((int)a[i][2]);
            if (a[i][1] == 1)
            {
                last1 = i;
            }
        }
        else if (a[i][1] == 2 && first2 == -1)
        {
            first2 = i;
        }
    }
    if (v == 1)
    {
        if (last1 != -1 && first2 != -1 && a[first2][0] * 2 > a[last1][0])
        {
            cap += a[first2][0] * 2 - a[last1][0];
            for (int i = 0; i < res.size(); ++i)
                if (res[i] == a[last1][2])
                {
                    res[i] = a[first2][2];
                    break;
                }
        }
    }
    cout << cap << endl;
    for (int i = 0; i < res.size(); ++i)
    {
        cout << res[i] << ' ';
    }

    return 0;
}


#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <math.h>
using namespace std;
#define LL long long

int main()
{
    int n, v;
    cin >> n >> v;
    vector<vector<double> > a(n, vector<double>(3));
    for (int i = 0; i < n; ++i)
    {
        int t, p;
        cin >> t >> p;
        a[i][1] = t;
        a[i][0] = 1.0 * p / t;
        a[i][2] = i + 1;
    }
    sort(a.begin(), a.end());
    reverse(a.begin(), a.end());
    vector<int> res;
    int cap = 0;
    int last1, first2 = -1;
    for (int i = 0; i < n; ++i)
    {
        if (v >= a[i][1])
        {
            v -= a[i][1];
            cap += a[i][0] * a[i][1];
            res.push_back((int)a[i][2]);
            if (a[i][1] == 1)
            {
                last1 = i;
            }
        }
        else if (a[i][1] == 2 && first2 == -1)
        {
            first2 = i;
        }
    }
    if (v == 1)
    {
        if (first2 != -1 && a[first2][0] * 2 > a[last1][0])
        {
            cap += a[first2][0] * 2 - a[last1][0];
            for (int i = 0; i < res.size(); ++i)
                if (res[i] == a[last1][2])
                {
                    res[i] = a[first2][2];
                    break;
                }
        }
    }
    cout << cap << endl;
    for (int i = 0; i < res.size(); ++i)
    {
        cout << res[i] << ' ';
    }

    return 0;
}


#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <math.h>
using namespace std;
#define LL long long

int main()
{
    int n, v;
    cin >> n >> v;
    vector<vector<double> > a(n, vector<double>(3));
    for (int i = 0; i < n; ++i)
    {
        int t, p;
        cin >> t >> p;
        a[i][1] = t;
        a[i][0] = 1.0 * p / t;
        a[i][2] = i + 1;
    }
    sort(a.begin(), a.end());
    reverse(a.begin(), a.end());
    vector<int> res;
    int cap = 0;
    for (int i = 0; i < n; ++i)
    {
        if (v >= a[i][1])
        {
            v -= a[i][1];
            cap += a[i][0] * a[i][1];
            res.push_back((int)a[i][2]);
        }
    }
    cout << cap << endl;
    for (int i = 0; i < res.size(); ++i)
    {
        cout << res[i];
    }

    return 0;
}


#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <math.h>
using namespace std;
#define LL long long

int main()
{
    int n, v;
    cin >> n >> v;
    vector<vector<double> > a(n, vector<double>(3));
    for (int i = 0; i < n; ++i)
    {
        int t, p;
        cin >> t >> p;
        a[i][1] = t;
        a[i][0] = 1.0 * p / t;
        a[i][2] = i + 1;
    }
    sort(a.begin(), a.end());
    reverse(a.begin(), a.end());
    vector<int> res;
    int cap = 0;
    for (int i = 0; i < n; ++i)
    {
        if (v >= a[i][1])
        {
            v -= a[i][1];
            cap += a[i][0] * a[i][1];
            res.push_back((int)a[i][2]);
        }
    }
    cout << cap << endl;
    for (int i = 0; i < res.size(); ++i)
    {
        cout << res[i] << ' ';
    }

    return 0;
}


#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <numeric>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <math.h>
using namespace std;
#define LL long long

int main()
{
    int n, v;
    cin >> n >> v;
    vector<vector<double> > a(n, vector<double>(3));
    for (int i = 0; i < n; ++i)
    {
        int t, p;
        cin >> t >> p;
        a[i][1] = t;
        a[i][0] = 1.0 * p / t;
        a[i][2] = i + 1;
    }
    sort(a.begin(), a.end());
    reverse(a.begin(), a.end());
    vector<int> res;
    int cap = 0;
    int last1, first2 = -1;
    for (int i = 0; i < n; ++i)
    {
        if (v >= a[i][1])
        {
            v -= a[i][1];
            cap += a[i][0] * a[i][1];
            res.push_back((int)a[i][2]);
            if (a[i][1] == 1)
            {
                last1 = i;
            }
        }
        else if (a[i][1] == 2 && first2 == -1)
        {
            first2 = i;
        }
    }
    if (v == 1)
    {
        if (a[first2][0] * 2 > a[last1][0])
        {
            cap += a[first2][0] * 2 - a[last1][0];
            for (int i = 0; i < res.size(); ++i)
                if (res[i] == a[last1][2])
                {
                    res[i] = a[first2][2];
                    break;
                }
        }
    }
    cout << cap << endl;
    for (int i = 0; i < res.size(); ++i)
    {
        cout << res[i] << ' ';
    }

    return 0;
}


#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>

using namespace std;

#define maxN 100000

int N, V;
int cap[maxN];
vector<int> kayak, catamaran;
int ans;
vector<int> indices;

int main()
{
    cin >> N >> V;
    for (int i = 0; i < N; i++)
    {
        int type;
        cin >> type >> cap[i];
        if (type == 1)
            kayak.push_back(i);
        else
            catamaran.push_back(i);
    }
    sort(kayak.begin(), kayak.end(), [](int i, int j) { return cap[i] < cap[j]; });
    sort(catamaran.begin(), catamaran.end(), [](int i, int j) { return cap[i] < cap[j]; });
    while (V > 0)
    {
        if (V == 1)
        {
            if (!kayak.empty())
            {
                ans += cap[kayak.back()];
                indices.push_back(kayak.back());
            }
            break;
        }
        else if (catamaran.empty())
        {
            if (kayak.empty())
                break;
            ans += cap[kayak.back()];
            indices.push_back(kayak.back());
            kayak.pop_back();
            V -= 1;
        }
        else if (kayak.size() < 1 || cap[kayak.back()] + cap[kayak[kayak.size() - 2]] < cap[catamaran.back()])
        {
            ans += cap[catamaran.back()];
            indices.push_back(catamaran.back());
            catamaran.pop_back();
            V -= 2;
        }
        else
        {
            ans += cap[kayak.back()];
            indices.push_back(kayak.back());
            kayak.pop_back();
            V -= 1;
        }
    }
    cout << ans << endl;
    bool w = false;
    for (int index: indices)
    {
        if (!w)
            w = true;
        else
            cout << " ";
        cout << index + 1;
    }
    cout << endl;
    return 0;
}


#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>

using namespace std;

#define maxN 100000

int N, V;
int cap[maxN];
vector<int> kayak, catamaran;
int ans;
vector<int> indices;

int main()
{
    cin >> N >> V;
    for (int i = 0; i < N; i++)
    {
        int type;
        cin >> type >> cap[i];
        if (type == 1)
            kayak.push_back(i);
        else
            catamaran.push_back(i);
    }
    sort(kayak.begin(), kayak.end(), [](int i, int j) { return cap[i] < cap[j]; });
    sort(catamaran.begin(), catamaran.end(), [](int i, int j) { return cap[i] < cap[j]; });
    while (V > 0)
    {
        if (V == 1)
        {
            if (!kayak.empty())
            {
                ans += cap[kayak.back()];
                indices.push_back(kayak.back());
            }
            break;
        }
        else if (catamaran.empty())
        {
            if (kayak.empty())
                break;
            ans += cap[kayak.back()];
            indices.push_back(kayak.back());
            V -= 1;
        }
        else if (kayak.size() < 1 || cap[kayak.back()] + cap[kayak[kayak.size() - 2]] < cap[catamaran.back()])
        {
            ans += cap[catamaran.back()];
            indices.push_back(catamaran.back());
            V -= 2;
        }
        else
        {
            ans += cap[kayak.back()];
            indices.push_back(kayak.back());
            V -= 1;
        }
    }
    cout << ans << endl;
    bool w = false;
    for (int index: indices)
    {
        if (!w)
            w = true;
        else
            cout << " ";
        cout << index + 1;
    }
    cout << endl;
    return 0;
}


#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>

using namespace std;

#define maxN 100000

int N, V;
int cap[maxN];
vector<int> kayak, catamaran;
int ans;
vector<int> indices;

int main()
{
    cin >> N >> V;
    for (int i = 0; i < N; i++)
    {
        int type;
        cin >> type >> cap[i];
        if (type == 1)
            kayak.push_back(i);
        else
            catamaran.push_back(i);
    }
    sort(kayak.begin(), kayak.end(), [](int i, int j) { return cap[i] < cap[j]; });
    sort(catamaran.begin(), catamaran.end(), [](int i, int j) { return cap[i] < cap[j]; });
    while (V > 0)
    {
        if (V == 1)
        {
            if (!kayak.empty())
            {
                ans += cap[kayak.back()];
                indices.push_back(kayak.back());
            }
            break;
        }
        else if (catamaran.empty())
        {
            if (kayak.empty())
                break;
            ans += cap[kayak.back()];
            indices.push_back(kayak.back());
            kayak.pop_back();
            V -= 1;
        }
        else if (kayak.size() < 2 || cap[kayak.back()] + cap[kayak[kayak.size() - 2]] < cap[catamaran.back()])
        {
            ans += cap[catamaran.back()];
            indices.push_back(catamaran.back());
            catamaran.pop_back();
            V -= 2;
        }
        else
        {
            ans += cap[kayak.back()];
            indices.push_back(kayak.back());
            kayak.pop_back();
            V -= 1;
        }
    }
    cout << ans << endl;
    bool w = false;
    for (int index: indices)
    {
        if (!w)
            w = true;
        else
            cout << " ";
        cout << index + 1;
    }
    cout << endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct v2{
    int i1, i2, c;
    bool operator<(const v2 &y) const{ return c > y.c; }
};

int N, V, T, C, A;
vector<int> ans;
vector<v2> all;
vector<pair<int, int> > one, two;

int main(){
    ios_base::sync_with_stdio(false);
    cin >> N >> V;
    for(int i=0; i<N; i++){
        cin >> T >> C;
        if(T==1) one.emplace_back(C, i);
        else two.emplace_back(C, i);
    }

    if(V&1){
        if(one.size()){
            A += one.back().first;
            ans.push_back(one.back().second);
            one.pop_back();
        }
        V--;
    }

    sort(one.begin(), one.end());
    sort(two.begin(), two.end());

    for(pair<int, int> p : two)
        all.push_back({p.second, -1, p.first});

    for(int i=one.size()%2; i+1<one.size(); i+=2)
        all.push_back({one[i].second, one[i+1].second, one[i].first+one[i+1].first});

    sort(all.begin(), all.end());

    for(v2 e : all){
        if(V<2) break; V-=2;
        A += e.c;
        ans.push_back(e.i1);
        if(e.i2 != -1) ans.push_back(e.i2);
    }

    if(one.size()%2 && V>=1){ A += one[0].first; ans.push_back(one[0].second); }

    cout << A << "\n";
    for(int idx : ans) cout << idx+1 << "\n";
    cout.flush();
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct v2{
    int i1, i2, c;
    bool operator<(const v2 &y) const{ return c > y.c; }
};

int N, V, T, C, A;
vector<int> ans;
vector<v2> all;
vector<pair<int, int> > one, two;

int main(){
    ios_base::sync_with_stdio(false);
    cin >> N >> V;
    for(int i=0; i<N; i++){
        cin >> T >> C;
        if(T==1) one.emplace_back(C, i);
        else two.emplace_back(C, i);
    }

    if(V&1){
        if(one.size()){
            A += one.back().first;
            ans.push_back(one.back().second);
            one.pop_back();
        }
        V--;
    }

    sort(one.begin(), one.end());
    sort(two.begin(), two.end());

    for(pair<int, int> p : two)
        all.push_back({p.second, -1, p.first});

    for(int i=one.size()%2; i+1<one.size(); i+=2)
        all.push_back({one[i].second, one[i+1].second, one[i].first+one[i+1].first});

    sort(all.begin(), all.end());

    for(v2 e : all){
        if(V<2) break; V-=2;
        A += e.c;
        ans.push_back(e.i1);
        if(e.i2 != -1) ans.push_back(e.i2);
    }

    cout << A << "\n";
    for(int idx : ans) cout << idx+1 << "\n";
    cout.flush();
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int N, V, T, C, A;
vector<pair<int, int> > one, two;

int main(){
    ios_base::sync_with_stdio(false);
    cin >> N >> V;
    for(int i=0; i<N; i++){
        cin >> T >> C;
        if(T==1) one.emplace_back(C, i);
        else two.emplace_back(C, i);
    }

    sort(one.begin(), one.end());
    reverse(one.begin(), one.end());
    sort(two.begin(), two.end());
    reverse(two.begin(), two.end());

    int best = 0, bi = 0, bj = 0;
    int capa = 0, i = 0, j = 0, use = 0;

    while(i<one.size() && use+1<=V){
        capa += one[i++].first;
        use++;
    }

    for(int ii=i; ii>=0; ii--){
        if(i>ii){ use--; i--; capa -= one[i].first; }
        while(j<two.size() && use+2<=V){
            capa += two[j++].first;
            use+=2;
        }
        if(capa > best){ best = capa; bi = ii; bj = j; }
    }

    cout << best << "\n";
    for(int k=0; k<bi; k++) cout << one[k].second+1 << "\n";
    for(int k=0; k<bj; k++) cout << two[k].second+1 << "\n";
    cout.flush();
    return 0;
}


#include <stdio.h>
#include <iostream>
#include <functional>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <vector>
#include <string>
#include <assert.h>
#include <cmath>
#include <stdlib.h>

#define i64 long long
#define se second
#define fi first
#define mp make_pair
#define pii pair<int, int>

#ifdef I_LOVE_NOVACO
    #define eprintf printf(">>> "); printf
#else
    #define eprintf none
#endif
void none(...) {}
using namespace std;
const i64 md = (i64)1e9+9;
const int maxn = (int)1e5+5;
vector<pair<int, int> > A;
pair<int, pair<int, int> > boat[maxn];

int f[maxn], Left[maxn];
int get(int l, int r) {
	if (l < 0 && r < 0) return 0;
	if (l <= 0) return f[r];
	return f[r] - f[l - 1];
}
int main() {
#ifdef I_LOVE_NOVACO
	freopen("input.txt", "r", stdin);
#else
	ios_base::sync_with_stdio(0);
#endif
	int n, v; cin >> n >> v;
	for (int i = 0; i < n; i++) {
		int tp, arg; cin >> tp >> arg;
		boat[i] = mp(arg, mp(tp, i));
	}
	sort(boat, boat + n);

	int curV = v, curAns = 0, Ans = 0;
	int lst = -1, pt = 0;

	boat[n] = mp(0, mp(2, -1));
	for (int i = 0; i <= n; i++) {
		if (boat[i].second.first == 1) {
			f[pt] = boat[i].first + (pt > 0 ? f[pt - 1] : 0);
			lst = pt, pt++;
		} else {
			Left[i] = lst;
		}
	}
	int id = n;

	for (int i = n; i >= 0; i--) {
		if (i < n)
			curV -= boat[i].second.first;
		curAns += boat[i].first;
		if (boat[i].second.first == 2 && curV >= 0) {
			int one = Left[i];
			int add = get(one - curV + 1, one);
			if (curAns + add > Ans) {
				Ans = curAns + add;
				id = i;
			}
		}
	}
	cout << Ans << "\n";
	if (id == n) {
		for (int i = id - 1; i >= 0; i--) {
			if (boat[i].second.first == 1 && v > 0) {
				cout << boat[i].second.second + 1 << " ";
					v--;
			}
		}
		return 0;
	}
	for (int i = n - 1; i >= id; i--) {
		cout << boat[i].second.second + 1 << " ";
		v -= boat[i].second.first;
	}
	for (int i = id - 1; i >= 0; i--) {
		if (boat[i].second.first == 1 && v > 0) {
			cout << boat[i].second.second + 1 << " ";
			v--;
		}
	}
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <functional>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <vector>
#include <string>
#include <assert.h>
#include <cmath>
#include <stdlib.h>

#define i64 long long
#define se second
#define fi first
#define mp make_pair
#define pii pair<int, int>

#ifdef I_LOVE_NOVACO
    #define eprintf printf(">>> "); printf
#else
    #define eprintf none
#endif
void none(...) {}
using namespace std;
const i64 md = (i64)1e9+9;
const int maxn = (int)1e5+5;
vector<pair<int, int> > A;
pair<int, pair<int, int> > boat[maxn];

int f[maxn], Left[maxn];
int get(int l, int r) {
	if (l <= 0) return f[r];
	return f[r] - f[l - 1];
}
int main() {
#ifdef I_LOVE_NOVACO
	freopen("input.txt", "r", stdin);
#else
	ios_base::sync_with_stdio(0);
#endif
	int n, v; cin >> n >> v;
	for (int i = 0; i < n; i++) {
		int tp, arg; cin >> tp >> arg;
		boat[i] = mp(arg, mp(tp, i));
	}
	sort(boat, boat + n);

	int curV = v, curAns = 0, Ans = 0;
	int lst = -1, pt = 0;
	if (boat[0].second.first == 1) {
		f[0] = boat[0].first;
		lst = 0;
		pt++;
	}
	boat[n] = mp(0, mp(2, -1));
	for (int i = 1; i <= n; i++) {
		if (boat[i].second.first == 1) {
			f[pt] = boat[i].first + (pt > 0 ? f[pt - 1] : 0);
			lst = pt, pt++;
		} else {
			Left[i] = lst;
		}
	}
	int id = n;

	for (int i = n; i >= 0; i--) {
		if (i < n)
			curV -= boat[i].second.first;
		curAns += boat[i].first;
		if (boat[i].second.first == 2 && curV >= 0) {
			int one = Left[i];
			int add = get(one - curV + 1, one);
			if (curAns + add > Ans) {
				Ans = curAns + add;
				id = i;
			}
		}
	}
	cout << Ans << "\n";
	if (id == n) {
		for (int i = id - 1; i >= 0; i--) {
			if (boat[i].second.first == 1 && v > 0) {
				cout << boat[i].second.second + 1 << " ";
					v--;
			}
		}
		return 0;
	}
	for (int i = n - 1; i >= id; i--) {
		cout << boat[i].second.second + 1 << " ";
		v -= boat[i].second.first;
	}
	for (int i = id - 1; i >= 0; i--) {
		if (boat[i].second.first == 1 && v > 0) {
			cout << boat[i].second.second + 1 << " ";
			v--;
		}
	}
	return 0;
}