#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
#define s second
#define f first
using namespace std;
const long maxn=110000;
pair<long,long> a[maxn]={},b[maxn]={};
long i,n,v,x,y,p=1,q=1,pa=0,pb=0,ans=0,sa[maxn]={},sb[maxn]={};
bool comp(pair<long,long> a,pair<long,long> b) {return a.f>b.f;}
int main() {
    cin >> n >> v;
    for (i=1;i<=n;i++) {
        cin >> x >> y;
        if (x==1) a[++pa]=make_pair(y,i);
            else b[++pb]=make_pair(y,i);
    }
    sort(a+1,a+pa+1,comp);sort(b+1,b+pb+1,comp);
    for (i=1;i<=pa;i++) sa[i]=sa[i-1]+a[i].f;
    for (i=1;i<=pb;i++) sb[i]=sb[i-1]+b[i].f;
    for (i=0;i<=pb;i++) {
        x=min(v/2,i);y=min(v-2*x,pa);
        if (sb[x]+sa[y]>ans) ans=sb[x]+sa[y];
    }
    for (i=0;i<=pb;i++) {
        x=min(v/2,i);y=min(v-2*x,pa);
        if (sb[x]+sa[y]==ans) break;
    }
    cout << ans << endl;
    for (i=1;i<=x;i++) cout << b[i].s << ' ';
    for (i=1;i<=y;i++) cout << a[i].s << ' ';
    cout << endl;
    return 0;
}


//ITNOG
#include<bits/stdc++.h>

using namespace std;
#define int long long
const int maxN = 100 + 10;
const int mod = 1000*1000*1000 + 7;

main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    int n, x; cin >> n >> x;
    vector< pair<int, int> > v[2];
    for(int i = 0; i < n; i ++)
    {
	  int t, p; cin >> t >> p;
	  t --;
	  v[t].push_back(make_pair(p, i));
    }
    for(int i = 0; i < 2; i ++)
	  sort(v[i].begin(), v[i].end());
    x = min(x, 2 * n);
    int st1 = 0, st2 = 0;
    vector<int> ans;
    int answer = 0;
    while(x && (st1 < v[0].size() || st2 < v[1].size()) )
    {
	  if(x > 1 && st2 < v[1].size() && v[1][st2].first > (st1 < v[0].size() ? v[0][st1].first : 0LL) + (st1 + 1 < v[0].size() ? v[0][st1 + 1].first : 0LL))
	  {
		ans.push_back(v[1][st2].second + 1);
		answer += v[1][st2].first;
		x -= 2; st2 ++; continue;
	  }

	  if(st1 < v[0].size())
	  {
		answer += v[0][st1].first;
		ans.push_back(v[0][st1].second + 1);
		x --;
		st1 ++;
	  }
	  else break;
    }
    cout << answer << endl;
    for(int i = 0; i < ans.size(); i ++)
	  cout << ans[i] << ' ';
    cout << endl;
    return 0;
}


//ITNOG
#include<bits/stdc++.h>

using namespace std;
#define int long long
const int maxN = 100 + 10;
const int mod = 1000*1000*1000 + 7;

main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    int n, x; cin >> n >> x;
    vector< pair<int, int> > v[2];
    for(int i = 0; i < n; i ++)
    {
	  int t, p; cin >> t >> p;
	  t --;
	  v[t].push_back(make_pair(p, i));
    }
    for(int i = 0; i < 2; i ++)
	  sort(v[i].begin(), v[i].end());
    x = min(x, 2 * n);
    int st1 = 0, st2 = 0;
    vector<int> ans;
    int answer = 0;
    while(x && (st1 < v[0].size() || st2 < v[1].size()) )
    {
	  if(x > 1 && st2 < v[1].size() && v[1][st2].first > (st1 < v[0].size() ? v[0][st1].first : 0LL) + (st1 + 1 < v[0].size() ? v[0][st1 + 1].first : 0LL))
	  {
		ans.push_back(v[1][st2].second + 1);
		answer += v[1][st2].first;
		x -= 2; st2 ++; continue;
	  }

	  if(st1 < v[0].size())
	  {
		answer += v[0][st1].first;
		ans.push_back(v[0][st1].second + 1);
		x --;
	  }
	  else break;
    }
    cout << answer << endl;
    for(int i = 0; i < ans.size(); i ++)
	  cout << ans[i] << ' ';
    cout << endl;
    return 0;
}


//ITNOG
#include<bits/stdc++.h>

using namespace std;
#define int long long
const int maxN = 100 + 10;
const int mod = 1000*1000*1000 + 7;

main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    int n, x; cin >> n >> x;
    vector< pair<int, int> > v[2];
    for(int i = 0; i < n; i ++)
    {
	  int t, p; cin >> t >> p;
	  t --;
	  v[t].push_back(make_pair(p, i));
    }
    for(int i = 0; i < 2; i ++)
	  sort(v[i].begin(), v[i].end(), greater<pair<int, int> >() );
    x = min(x, 2 * n);
    int st1 = 0, st2 = 0;
    vector<int> ans;
    int answer = 0;
    while(x && (st1 < v[0].size() || st2 < v[1].size()) )
    {
	  if(x > 1 && st2 < v[1].size() && v[1][st2].first > (st1 < v[0].size() ? v[0][st1].first : 0LL) + (st1 + 1 < v[0].size() ? v[0][st1 + 1].first : 0LL))
	  {
		ans.push_back(v[1][st2].second + 1);
		answer += v[1][st2].first;
		x -= 2; st2 ++; continue;
	  }

	  if(st1 < v[0].size())
	  {
		answer += v[0][st1].first;
		ans.push_back(v[0][st1].second + 1);
		x --;
		st1 ++;
	  }
	  else break;
    }
    cout << answer << endl;
    for(int i = 0; i < ans.size(); i ++)
	  cout << ans[i] << ' ';
    cout << endl;
    return 0;
}


#include<cstdio>
#include<vector>
#include<algorithm>

std::vector<std::pair<int,int> > kayak,catamaran;
const int N=(int)(1e5+1);
int n,v,kayakSum[N],catamaranSum[N],type,capacity,s1,s2,maxCapacity;

void get(std::vector<std::pair<int,int> >& a,int sum[N]) {
    std::sort(a.begin(),a.end());
    std::reverse(a.begin(),a.end());
    sum[0]=0;
    for(int i=1; i<=(int)a.size(); ++i) {
        sum[i]=sum[i-1]+a[i-1].first;
    }
}

int main() {
    scanf("%d%d",&n,&v);
    for(int i=1; i<=n; ++i) {
        scanf("%d%d",&type,&capacity);
        if(type==1) {
            kayak.push_back(std::make_pair(capacity,i));
        } else {
            catamaran.push_back(std::make_pair(capacity,i));
        }
    }
    get(kayak,kayakSum);
    get(catamaran,catamaranSum);
    maxCapacity=0;
    for(int i=0; i<=std::min(n,v); ++i) {
        int j=std::min((v-i)/2,(int)catamaran.size());
        int temp=kayakSum[i]+catamaranSum[j];
        if(temp>maxCapacity) {
            maxCapacity=temp;
            s1=i;
            s2=j;
        }
    }
    printf("%d\n",maxCapacity);
    for(int i=0; i<s1; ++i) {
        printf("%d%c",kayak[i].second,(i!=s1-1||s2)?' ':'\n');
    }
    for(int i=0; i<s2; ++i) {
        printf("%d%c",catamaran[i].second,(i!=s2-1)?' ':'\n');
    }
    return 0;
}


//Copyright (c) Nguyen Huy Truong Nam
#pragma comment(linker, "/STACK:0x04000000")
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cctype>
#include <cassert>
#include <climits>
#include <ctime>
#include <algorithm>
#include <limits>
#include <iterator>
#include <string>
#include <vector>
#include <deque>
#include <set>
#include <map>

using namespace std;
typedef unsigned int uint;
typedef long long i64;
typedef unsigned long long ui64;
typedef long double ld;

const int MAX_N = 100005;
vector<pair<int, int>> boats[2];
int sum[MAX_N];

int main() {
#ifdef NOVACO
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    int v;
    cin >> n >> v;
    for (int i = 0; i < n; i++) {
        int t;
        int p;
        cin >> t >> p;
        t--;
        boats[t].push_back(make_pair(p, i + 1));
    }
    sort(boats[0].rbegin(), boats[0].rend());
    sort(boats[1].rbegin(), boats[1].rend());
    if (boats[0].size()) {
        sum[0] = boats[0][0].first;
        for (int i = 1; i < boats[0].size(); i++) {
            sum[i] = sum[i - 1] + boats[0][i].first;
        }
    }
    int res_n1 = -1;
    int res_n2 = -1;
    int res_sum = -1;
    int sum_2 = 0;
    for (int i = -1; i < (int)boats[1].size() && v >= 2 * (i + 1); i++) {
        sum_2 += i >= 0 ? boats[1][i].first : 0;
        int n2 = i + 1;
        int n1 = min((int)boats[0].size(), v - 2 * n2);
        int sum_1 = n1 > 0 ? sum[n1 - 1] : 0;
        if (res_sum < sum_1 + sum_2) {
            res_sum = sum_1 + sum_2;
            res_n1 = n1;
            res_n2 = n2;
        }
    }
    cout << res_sum << "\n";
    for (int i = 0; i < res_n1; i++) {
        cout << boats[0][i].second << " ";
    }
    for (int i = 0; i < res_n2; i++) {
        cout << boats[1][i].second << " ";
    }
    cout << "\n";
}


//Copyright (c) Nguyen Huy Truong Nam
#pragma comment(linker, "/STACK:0x04000000")
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cctype>
#include <cassert>
#include <climits>
#include <ctime>
#include <algorithm>
#include <limits>
#include <iterator>
#include <string>
#include <vector>
#include <deque>
#include <set>
#include <map>

using namespace std;
typedef unsigned int uint;
typedef long long i64;
typedef unsigned long long ui64;
typedef long double ld;

const int MAX_N = 100005;
vector<pair<int, int>> boats[2];
int sum[MAX_N];

int main() {
#ifdef NOVACO
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    int v;
    cin >> n >> v;
    for (int i = 0; i < n; i++) {
        int t;
        int p;
        cin >> t >> p;
        t--;
        boats[t].push_back(make_pair(p, i + 1));
    }
    sort(boats[0].rbegin(), boats[0].rend());
    sort(boats[1].rbegin(), boats[1].rend());
    if (boats[0].size()) {
        sum[0] = boats[0][0].first;
        for (int i = 1; i < boats[0].size(); i++) {
            sum[i] = sum[i - 1] + boats[0][i].first;
        }
    }
    int res_n1 = -1;
    int res_n2 = -1;
    int res_sum = -1;
    int sum_2 = 0;
    for (int i = -1; i < (int)boats[1].size(); i++) {
        sum_2 += i >= 0 ? boats[1][i].first : 0;
        int n2 = i + 1;
        int n1 = min((int)boats[0].size(), v - 2 * n2);
        int sum_1 = n1 > 0 ? sum[n1 - 1] : 0;
        if (res_sum < sum_1 + sum_2) {
            res_sum = sum_1 + sum_2;
            res_n1 = n1;
            res_n2 = n2;
        }
    }
    cout << res_sum << "\n";
    for (int i = 0; i < res_n1; i++) {
        cout << boats[0][i].second << " ";
    }
    for (int i = 0; i < res_n2; i++) {
        cout << boats[1][i].second << " ";
    }
    cout << "\n";
}


//Copyright (c) Nguyen Huy Truong Nam
#pragma comment(linker, "/STACK:0x04000000")
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cctype>
#include <cassert>
#include <climits>
#include <ctime>
#include <algorithm>
#include <limits>
#include <iterator>
#include <string>
#include <vector>
#include <deque>
#include <set>
#include <map>

using namespace std;
typedef unsigned int uint;
typedef long long i64;
typedef unsigned long long ui64;
typedef long double ld;

const int MAX_N = 100005;
vector<pair<int, int>> boats[2];
int sum[MAX_N];

int main() {
#ifdef NOVACO
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int n;
    int v;
    cin >> n >> v;
    for (int i = 0; i < n; i++) {
        int t;
        int p;
        cin >> t >> p;
        t--;
        boats[t].push_back(make_pair(p, i + 1));
    }
    sort(boats[0].rbegin(), boats[0].rend());
    sort(boats[1].rbegin(), boats[1].rend());
    sum[0] = boats[0][0].first;
    for (int i = 1; i < boats[0].size(); i++) {
        sum[i] = sum[i - 1] + boats[0][i].first;
    }
    int res_n1 = -1;
    int res_n2 = -1;
    int res_sum = -1;
    int sum_2 = 0;
    for (int i = -1; i < (int)boats[1].size(); i++) {
        sum_2 += i >= 0 ? boats[1][i].first : 0;
        int n2 = i + 1;
        int n1 = min((int)boats[0].size(), v - 2 * n2);
        int sum_1 = n1 > 0 ? sum[n1 - 1] : 0;
        if (res_sum < sum_1 + sum_2) {
            res_sum = sum_1 + sum_2;
            res_n1 = n1;
            res_n2 = n2;
        }
    }
    cout << res_sum << "\n";
    for (int i = 0; i < res_n1; i++) {
        cout << boats[0][i].second << " ";
    }
    for (int i = 0; i < res_n2; i++) {
        cout << boats[1][i].second << " ";
    }
    cout << "\n";
}


#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>

using namespace std;

vector < short > types(1);
vector < unsigned long > capacity(1);

void Print(vector < vector < unsigned long > > w, int i, int j)
{
	if (w[i][j] == 0)
		return;

	if ( w[i][j] == w[i][j-1] )
		Print(w, i, j-1);
	else
	{
		cout << j << ' ';
		Print(w, i - types[j], j - 1);
	}
}

int main()
{
	unsigned long n, vol;
	short a;
	unsigned long b;

	cin >> n >> vol;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b;
		types.push_back(a);
		capacity.push_back(b);
	}

	vector < vector < unsigned long > > w(vol + 1, vector<unsigned long>(n + 1, 0));

	for (int i = 1; i < vol + 1; ++i)
		for (int j = 1; j < n + 1; ++j)
		{
//			unsigned long q = capacity[j];
//			short e = types[j];
//			unsigned long r = w[i][j-1], t = w[i - e][j-1] + q;
			w[i][j] = w[i][j-1];
			if ( i - types[j] >= 0 ) w[i][j] = max(w[i][j], w[i - types[j]][j-1] + capacity[j]);
		}

	cout << w[vol][n] << endl;
	Print(w, vol, n);

	return 0;
}


#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>

using namespace std;

vector < short > types(1);
vector < unsigned > capacity(1);

void Print(vector < vector < unsigned long > > & w, int i, int j)
{
	if (w[i][j] == 0)
		return;

	if ( w[i][j] == w[i][j-1] )
		Print(w, i, j-1);
	else
	{
		cout << j << ' ';
		Print(w, i - types[j], j - 1);
	}
}

int main()
{
	unsigned long vol;
	short a;
	unsigned n, b;

	cin >> n >> vol;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b;
		types.push_back(a);
		capacity.push_back(b);
	}

	vector < vector < unsigned long > > w(vol + 1, vector<unsigned long>(n + 1, 0));

	for (int i = 1; i < vol + 1; ++i)
		for (int j = 1; j < n + 1; ++j)
		{
//			unsigned long q = capacity[j];
//			short e = types[j];
//			unsigned long r = w[i][j-1], t = w[i - e][j-1] + q;
			w[i][j] = w[i][j-1];
			if ( i - types[j] >= 0 ) w[i][j] = max(w[i][j], w[i - types[j]][j-1] + capacity[j]);
		}

	cout << w[vol][n] << endl;
	Print(w, vol, n);

	return 0;
}


#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>

using namespace std;

vector < short > types(1);
vector < unsigned > capacity(1);

void Print(vector < vector < unsigned > > & w, int i, int j)
{
	if (w[i][j] == 0)
		return;

	if ( w[i][j] == w[i][j-1] )
		Print(w, i, j-1);
	else
	{
		cout << j << ' ';
		Print(w, i - types[j], j - 1);
	}
}

int main()
{
	unsigned vol;
	short a;
	unsigned n, b;

	cin >> n >> vol;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b;
		types.push_back(a);
		capacity.push_back(b);
	}

	vector < vector < unsigned > > w(vol + 1, vector<unsigned>(n + 1, 0));

	for (int i = 1; i < vol + 1; ++i)
		for (int j = 1; j < n + 1; ++j)
		{
//			unsigned long q = capacity[j];
//			short e = types[j];
//			unsigned long r = w[i][j-1], t = w[i - e][j-1] + q;
			w[i][j] = w[i][j-1];
			if ( i - types[j] >= 0 ) w[i][j] = max(w[i][j], w[i - types[j]][j-1] + capacity[j]);
		}

	cout << w[vol][n] << endl;
	Print(w, vol, n);

	return 0;
}


#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>

using namespace std;

vector < short > types(1);
vector < unsigned long > capacity(1);

void Print(vector < vector < unsigned long > > & w, int i, int j)
{
	if (w[i][j] == 0)
		return;

	if ( w[i][j] == w[i][j-1] )
		Print(w, i, j-1);
	else
	{
		cout << j << ' ';
		Print(w, i - types[j], j - 1);
	}
}

int main()
{
	unsigned long n, vol;
	short a;
	unsigned long b;

	cin >> n >> vol;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b;
		types.push_back(a);
		capacity.push_back(b);
	}

	vector < vector < unsigned long > > w(vol + 1, vector<unsigned long>(n + 1, 0));

	for (int i = 1; i < vol + 1; ++i)
		for (int j = 1; j < n + 1; ++j)
		{
//			unsigned long q = capacity[j];
//			short e = types[j];
//			unsigned long r = w[i][j-1], t = w[i - e][j-1] + q;
			w[i][j] = w[i][j-1];
			if ( i - types[j] >= 0 ) w[i][j] = max(w[i][j], w[i - types[j]][j-1] + capacity[j]);
		}

	cout << w[vol][n] << endl;
	Print(w, vol, n);

	return 0;
}


#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>

using namespace std;

int main()
{
	int vol, n, b, a, res = 0;

	vector < pair < int, int > > canoe;
	vector < pair < int, int > > cata;

	cin >> n >> vol;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b;
		if ( a == 1 )
			canoe.push_back(make_pair(b, i + 1));
		else
			cata.push_back(make_pair(b, i + 1));

	}

	sort(canoe.begin(), canoe.end());
	sort(cata.begin(), cata.end());

	int can = canoe.size();
	int cat = cata.size();

	if ( vol & 1 && can > 0 )
		res = canoe[--can].first, --vol;

	bool flag = true;
	while ( flag && vol > 0 && (cat || can) )
	{
		flag = false;
		if ( can >= 2 && cat )
		{
			if ( cata[cat - 1].first > canoe[can - 1].first + canoe[can - 2].first )
				res += cata[--cat].first;
			else
				res += canoe[can - 1].first + canoe[can - 2].first, can -= 2;

			vol -= 2;
			flag = true;
		}
		else if ( cat )
			while ( vol > 1 && cat )
			{
				res += cata[--cat].first;
				vol -= 2;
				flag = true;
			}
		else if ( can )
			while ( vol > 0 && can )
			{
				res += canoe[--can].first;
				--vol;
				flag = true;
			}
	}

	cout << res << endl;
	for (; cat < cata.size(); ++cat)
		cout << cata[cat].second << ' ';
	for (; can < canoe.size(); ++can)
		cout << canoe[can].second << ' ';
	return 0;
}


#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>

using namespace std;

int main()
{
	int vol, n, b, a, res = 0;

	vector < pair < int, int > > canoe;
	vector < pair < int, int > > cata;

	cin >> n >> vol;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b;
		if ( a == 1 )
			canoe.push_back(make_pair(b, i + 1));
		else
			cata.push_back(make_pair(b, i + 1));

	}

	sort(canoe.begin(), canoe.end());
	sort(cata.begin(), cata.end());

	int can = canoe.size();
	int cat = cata.size();

	if ( vol & 1 && can > 0 )
		res = canoe[--can].first, --vol;

	while ( vol > 0 && (cat || can) )
		if ( can >= 2 && cat )
		{
			if ( cata[cat - 1].first > canoe[can - 1].first + canoe[can - 2].first )
				res += cata[--cat].first;
			else
				res += canoe[can - 1].first + canoe[can - 2].first, can -= 2;

			vol -= 2;
		}
		else if ( cat )
			while ( vol > 0 && cat )
			{
				res += cata[--cat].first;
				vol -= 2;
			}
		else if ( can )
			while ( vol > 0 && can )
			{
				res += canoe[--can].first;
				--vol;
			}

	cout << res << endl;
	for (; cat < cata.size(); ++cat)
		cout << cata[cat].second << ' ';
	for (; can < canoe.size(); ++can)
		cout << canoe[can].second << ' ';
	return 0;
}


#include <iostream>
#include <map>
#include <stack>
#include <vector>
#include <algorithm>
#include <string>
#include <utility>

using namespace std;

int main()
{
	int vol, n, b, a, res = 0;

	vector < pair < int, int > > canoe;
	vector < pair < int, int > > cata;

	cin >> n >> vol;
	for (int i = 0; i < n; ++i)
	{
		cin >> a >> b;
		if ( a == 1 )
			canoe.push_back(make_pair(b, i + 1));
		else
			cata.push_back(make_pair(b, i + 1));

	}

	sort(canoe.begin(), canoe.end());
	sort(cata.begin(), cata.end());

	int can = canoe.size();
	int cat = cata.size();

	if ( vol & 1 && can > 0 )
		res = canoe[--can].first, --vol;

	while ( vol > 0 && (cat || can) )
		if ( can >= 2 && cat )
		{
			if ( cata[cat - 1].first > canoe[can - 1].first + canoe[can - 2].first )
				res += cata[--cat].first;
			else
				res += canoe[can - 1].first + canoe[can - 2].first, can -= 2;

			vol -= 2;
		}
		else if ( cat )
			while ( vol && cat )
			{
				res += cata[--cat].first;
				vol -= 2;
			}
		else if ( can )
			while ( vol && can )
			{
				res += canoe[--can].first;
				--vol;
			}

	cout << res << endl;
	for (; cat < cata.size(); ++cat)
		cout << cata[cat].second << ' ';
	for (; can < canoe.size(); ++can)
		cout << canoe[can].second << ' ';
	return 0;
}


//by maximumSHOT!

#define _USE_MATH_DEFINES

#include <iostream>
#include <cmath>
#include <math.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <time.h>
#include <clocale>
#include <fstream>
//#include <conio.h>

using namespace std;

#define forx(i,n) for(int i(0);i < n;i++)
#define vec vector
#define mp make_pair
#define ALL(x) (x).begin(), (x).end()

typedef long L;
typedef long long LL;
typedef long double LD;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<double> vdouble;
typedef vector<vector<double>> vvdouble;
typedef vec<bool> vbool;
typedef vec<vec<bool>> vvbool;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef pair<double,int> pdi;
typedef pair<int,double> pid;
typedef pair<LL, LL> pll;
typedef unsigned long long ull;
typedef unsigned int ui;
const int inf = 1000 * 1000 * 1000;
const LL inf64 = LL(inf) * inf;
template<typename T>
inline T Sqr(T a){return a*a;}
const LL base = inf + 7;
struct Tripple
{
    int first;
    int second;
    int third;

    inline void make_tripple(int a,int b,int c)
    {
        first  = a;
        second = b;
        third  = c;
    }
};
inline bool cmp1(Tripple a,Tripple b)
{
    return a.first < b.first;
}
inline bool cmp2(Tripple a,Tripple b)
{
    return a.second < b.second;
}
inline bool cmp3(Tripple a,Tripple b)
{
    return a.third < b.third;
}
template<typename T> inline T inc(T &a, T b = 1)
{
    a += b;
}
template<typename T> inline T dec(T &a, T b = 1)
{
    a -= b;
}

// GL begin

// GL end

//Functions begin

//Functions end

bool solve()
{
    ios_base::sync_with_stdio(0);
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    ofstream fout2("input.txt");
    //#define cin fin
    //#define cout fout

    LL n, v, ans = 0;

    cin >> n >> v;

    vec<pll> m[2];
    vec<LL> order;

    for(int i(0);i < n;i++)
    {
        LL t, p;
        cin >> t >> p;
        m[t - 1].push_back(mp(p, i + 1));
    }

    sort(ALL(m[0]));
    sort(ALL(m[1]));

    if(v % 2)
    {
        v--;
        ans += m[0].back().first;
        order.push_back(m[0].back().second);
        m[0].pop_back();
    }

    vec<pair<LL, pll>> mb;

    for(int i(0);i < m[1].size();i++) mb.push_back(mp(m[1][i].first, mp(m[1][i].second, m[1][i].second)));
    for(int i(m[0].size() - 1);i > 0;i -= 2) mb.push_back(mp(m[0][i].first + m[0][i - 1].first, mp(m[0][i].second, m[0][i - 1].second)));

    sort(ALL(mb));

    for(int i(mb.size() - 1);i >= 0 && v;i--)
    {
        LL delt = mb[i].first;
        LL l = mb[i].second.first;
        LL r = mb[i].second.second;
        ans += delt;
        v -= 2;
        if(l == r) order.push_back(l);
        else order.push_back(l), order.push_back(r);
    }

    if(v && m[0].size() % 2) ans += m[0].front().first, order.push_back(m[0].front().second);

    cout << ans << '\n';

    for(auto i : order) cout << i << ' ';

    //_getch();
    return true;
}

int main(int argc,char **argv)
{
    //while(solve());
    solve();

    return 0;
}


//by maximumSHOT!

#define _USE_MATH_DEFINES

#include <iostream>
#include <cmath>
#include <math.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <time.h>
#include <clocale>
#include <fstream>
//#include <conio.h>

using namespace std;

#define forx(i,n) for(int i(0);i < n;i++)
#define vec vector
#define mp make_pair
#define ALL(x) (x).begin(), (x).end()

typedef long L;
typedef long long LL;
typedef long double LD;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<double> vdouble;
typedef vector<vector<double>> vvdouble;
typedef vec<bool> vbool;
typedef vec<vec<bool>> vvbool;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef pair<double,int> pdi;
typedef pair<int,double> pid;
typedef pair<LL, LL> pll;
typedef unsigned long long ull;
typedef unsigned int ui;
const int inf = 1000 * 1000 * 1000;
const LL inf64 = LL(inf) * inf;
template<typename T>
inline T Sqr(T a){return a*a;}
const LL base = inf + 7;
struct Tripple
{
    int first;
    int second;
    int third;

    inline void make_tripple(int a,int b,int c)
    {
        first  = a;
        second = b;
        third  = c;
    }
};
inline bool cmp1(Tripple a,Tripple b)
{
    return a.first < b.first;
}
inline bool cmp2(Tripple a,Tripple b)
{
    return a.second < b.second;
}
inline bool cmp3(Tripple a,Tripple b)
{
    return a.third < b.third;
}
template<typename T> inline T inc(T &a, T b = 1)
{
    a += b;
}
template<typename T> inline T dec(T &a, T b = 1)
{
    a -= b;
}

// GL begin

// GL end

//Functions begin

//Functions end

bool solve()
{
    ios_base::sync_with_stdio(0);
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    ofstream fout2("input.txt");
    //#define cin fin
    //#define cout fout

    LL n, v, ans = 0;

    cin >> n >> v;

    vec<pll> m[2];
    vec<LL> order;

    for(int i(0);i < n;i++)
    {
        LL t, p;
        cin >> t >> p;
        m[t - 1].push_back(mp(p, i + 1));
    }

    sort(ALL(m[0]));
    sort(ALL(m[1]));

    if(v % 2 && m[0].size())
    {
        v--;
        ans += m[0].back().first;
        order.push_back(m[0].back().second);
        m[0].pop_back();
    }

    vec<pair<LL, pll>> mb;

    for(int i(0);i < m[1].size();i++) mb.push_back(mp(m[1][i].first, mp(m[1][i].second, m[1][i].second)));
    for(int i(m[0].size() - 1);i > 0;i -= 2) mb.push_back(mp(m[0][i].first + m[0][i - 1].first, mp(m[0][i].second, m[0][i - 1].second)));

    sort(ALL(mb));

    for(int i(mb.size() - 1);i >= 0 && v > 1;i--)
    {
        LL delt = mb[i].first;
        LL l = mb[i].second.first;
        LL r = mb[i].second.second;
        ans += delt;
        v -= 2;
        if(l == r) order.push_back(l);
        else order.push_back(l), order.push_back(r);
    }

    if(v && m[0].size() % 2) ans += m[0].front().first, order.push_back(m[0].front().second);

    cout << ans << '\n';

    for(auto i : order) cout << i << ' ';

    //_getch();
    return true;
}

int main(int argc,char **argv)
{
    //while(solve());
    solve();

    return 0;
}


//by maximumSHOT!

#define _USE_MATH_DEFINES

#include <iostream>
#include <cmath>
#include <math.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <time.h>
#include <clocale>
#include <fstream>
//#include <conio.h>

using namespace std;

#define forx(i,n) for(int i(0);i < n;i++)
#define vec vector
#define mp make_pair
#define ALL(x) (x).begin(), (x).end()

typedef long L;
typedef long long LL;
typedef long double LD;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<double> vdouble;
typedef vector<vector<double>> vvdouble;
typedef vec<bool> vbool;
typedef vec<vec<bool>> vvbool;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef pair<double,int> pdi;
typedef pair<int,double> pid;
typedef pair<LL, LL> pll;
typedef unsigned long long ull;
typedef unsigned int ui;
const int inf = 1000 * 1000 * 1000;
const LL inf64 = LL(inf) * inf;
template<typename T>
inline T Sqr(T a){return a*a;}
const LL base = inf + 7;
struct Tripple
{
    int first;
    int second;
    int third;

    inline void make_tripple(int a,int b,int c)
    {
        first  = a;
        second = b;
        third  = c;
    }
};
inline bool cmp1(Tripple a,Tripple b)
{
    return a.first < b.first;
}
inline bool cmp2(Tripple a,Tripple b)
{
    return a.second < b.second;
}
inline bool cmp3(Tripple a,Tripple b)
{
    return a.third < b.third;
}
template<typename T> inline T inc(T &a, T b = 1)
{
    a += b;
}
template<typename T> inline T dec(T &a, T b = 1)
{
    a -= b;
}

// GL begin

// GL end

//Functions begin

//Functions end

bool solve()
{
    ios_base::sync_with_stdio(0);
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    ofstream fout2("input.txt");
    //#define cin fin
    //#define cout fout

    LL n, v, ans = 0;

    cin >> n >> v;

    vec<pll> m[2];
    vec<LL> order;

    for(int i(0);i < n;i++)
    {
        LL t, p;
        cin >> t >> p;
        m[t - 1].push_back(mp(p, i + 1));
    }

    sort(ALL(m[0]));
    sort(ALL(m[1]));

    if(v % 2)
    {
        v--;
        ans += m[0].back().first;
        order.push_back(m[0].back().second);
        m[0].pop_back();
    }

    vec<pair<LL, pll>> mb;

    for(int i(0);i < m[1].size();i++) mb.push_back(mp(m[1][i].first, mp(m[1][i].second, m[1][i].second)));
    for(int i(m[0].size() - 1);i > 0;i -= 2) mb.push_back(mp(m[0][i].first + m[0][i - 1].first, mp(m[0][i].second, m[0][i - 1].second)));

    sort(ALL(mb));

    for(int i(mb.size() - 1);i >= 0 && v;i--)
    {
        LL delt = mb[i].first;
        LL l = mb[i].second.first;
        LL r = mb[i].second.second;
        ans += delt;
        v -= 2;
        if(l == r) order.push_back(l);
        else order.push_back(l), order.push_back(r);
    }

    cout << ans << '\n';

    for(auto i : order) cout << i << ' ';

    //_getch();
    return true;
}

int main(int argc,char **argv)
{
    //while(solve());
    solve();

    return 0;
}


//by maximumSHOT!

#define _USE_MATH_DEFINES

#include <iostream>
#include <cmath>
#include <math.h>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <time.h>
#include <clocale>
#include <fstream>
//#include <conio.h>

using namespace std;

#define forx(i,n) for(int i(0);i < n;i++)
#define vec vector
#define mp make_pair
#define ALL(x) (x).begin(), (x).end()

typedef long L;
typedef long long LL;
typedef long double LD;
typedef vector<int> vint;
typedef vector<vint> vvint;
typedef vector<double> vdouble;
typedef vector<vector<double>> vvdouble;
typedef vec<bool> vbool;
typedef vec<vec<bool>> vvbool;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;
typedef pair<double,int> pdi;
typedef pair<int,double> pid;
typedef pair<LL, LL> pll;
typedef unsigned long long ull;
typedef unsigned int ui;
const int inf = 1000 * 1000 * 1000;
const LL inf64 = LL(inf) * inf;
template<typename T>
inline T Sqr(T a){return a*a;}
const LL base = inf + 7;
struct Tripple
{
    int first;
    int second;
    int third;

    inline void make_tripple(int a,int b,int c)
    {
        first  = a;
        second = b;
        third  = c;
    }
};
inline bool cmp1(Tripple a,Tripple b)
{
    return a.first < b.first;
}
inline bool cmp2(Tripple a,Tripple b)
{
    return a.second < b.second;
}
inline bool cmp3(Tripple a,Tripple b)
{
    return a.third < b.third;
}
template<typename T> inline T inc(T &a, T b = 1)
{
    a += b;
}
template<typename T> inline T dec(T &a, T b = 1)
{
    a -= b;
}

// GL begin

// GL end

//Functions begin

//Functions end

bool solve()
{
    ios_base::sync_with_stdio(0);
    ifstream fin("input.txt");
    ofstream fout("output.txt");
    ofstream fout2("input.txt");
    //#define cin fin
    //#define cout fout

    LL n, v, ans = 0;

    cin >> n >> v;

    vec<pll> m[2];
    vec<LL> order;

    for(int i(0);i < n;i++)
    {
        LL t, p;
        cin >> t >> p;
        m[t - 1].push_back(mp(p, i + 1));
    }

    sort(ALL(m[0]));
    sort(ALL(m[1]));

    if(v % 2)
    {
        v--;
        ans += m[0].back().first;
        order.push_back(m[0].back().second);
        m[0].pop_back();
    }

    vec<pair<LL, pll>> mb;

    for(int i(0);i < m[1].size();i++) mb.push_back(mp(m[1][i].first, mp(m[1][i].second, m[1][i].second)));
    for(int i(0);i < m[0].size() - 1;i += 2) mb.push_back(mp(m[0][i].first + m[0][i + 1].first, mp(m[0][i].second, m[0][i + 1].second)));

    sort(ALL(mb));

    for(int i(mb.size() - 1);i >= 0 && v;i--)
    {
        LL delt = mb[i].first;
        LL l = mb[i].second.first;
        LL r = mb[i].second.second;
        ans += delt;
        v -= 2;
        if(l == r) order.push_back(l);
        else order.push_back(l), order.push_back(r);
    }

    cout << ans << '\n';

    for(auto i : order) cout << i << ' ';

    //_getch();
    return true;
}

int main(int argc,char **argv)
{
    //while(solve());
    solve();

    return 0;
}


#define _SOLUTION                                                                                \
                                                                                \
                                                                                \
void solve() {                                                                                \
    $I2(int, n, v);                                                                                \
    tup2i(X, int, t, int, p);                                                                      \
    $Ix(X, vehicles, n);                                                                           \
                                                                                \
    seqarr(kayaks, _filter(_.t == 1, vehicles));                                                   \
    seqarr(cats, _filter(_.t == 2, vehicles));                                                     \
                                                                                \
    _sortf(kayaks, Lcmp_d(p));                                                                     \
    _sortf(cats, Lcmp_d(p));                                                                       \
                                                                                \
    seqarr(a1, IW(0) %lcat _fold(x, 0, x + _.p, cats));                                            \
    seqarr(a2, IW(0) %lcat _fold(x, 0, x + _.p, kayaks));                                          \
                                                                                \
    $$ ways = _gen(x, 0, 2*x <= v && x <= xlen(cats), PAIR(x, min(v - 2*x, xlen(kayaks))), x + 1); \
    $$ ways2 = _map(ways, PAIR(_, a1[_.f] + a2[_.s]));                                             \
    $$ res = _collapse(x, _.s > x.s ? _ : x, ways2);                                               \
                                                                                \
    $$ idxs = _map(_take(res.f.f, cats) %lcat _take(res.f.s, kayaks), _.idx + 1);                  \
                                                                                \
    _w_(res.s);                                                                                \
    _wi(idxs);                                                                                \
}                                                                                \
                                                                                \
_END_SOL                                                                                \
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ====== <<< PREWRITTEN CODE >>> ============================================
//
#pragma comment(linker, "/STACK:32000000")
#define _CRT_SECURE_NO_DEPRECATE
#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <stdarg.h>
#include <memory.h>
#include <string.h>
#include <assert.h>
#include <type_traits>
#include <limits>
#include <hash_map>
#include <hash_set>
using namespace std;
#define gcc_typename typename
using namespace __gnu_cxx;
#define LL_SPEC "%I64d"
#define ITER_WRITE inline void _write() const { _wstr("["); write_iterable(*this, SepComma()); _wstr("]"); }
#define SEQ_TYPE(x) const x
#define FUNC2(x,y) x##y
#define FUNC1(x,y) FUNC2(x,y)
#define FUNC(x) FUNC1(x,__COUNTER__)
#define STRUCT_NAME FUNC(struct_)
struct _DummyType {};
template<typename T>
struct ValueType {
	typedef typename remove_reference<T>::type clean_type;
	typedef typename clean_type::value_type type;
};
#define _wsp printf(" ")
#define _wlf printf("\n")
#define _wstr(s) printf("%s", s)
#define cmp_a(a) a < other.a
#define cmp_aa(a, b) cmp_a(a) || (a == other.a && b < other.b)
#define Lcmp_d(a) _1.a > _2.a
template<typename T>
struct item_type { typedef typename T::value_type type; };
template<typename T>
struct item_type<T*> { typedef T type; };
template<typename T, size_t sz>
struct item_type<T[sz]> { typedef T type; };
template<typename T, size_t sz>
struct item_type<T(&)[sz]> { typedef T type; };
template<typename T>
struct item_type<T*&> { typedef T type; };
template<typename T>
struct item_type<T**> { typedef T type; };
template<typename T>
struct item_type<T**&> { typedef T type; };
template<typename T>
struct _null { inline static T value() { return T(-1); } };
template<typename IterableType>
struct citerator
{
	typedef typename IterableType::value_type value_type;
	static inline value_type resolve(const IterableType &a, typename IterableType::iterator it)
		{ return a.resolve_iterator(it); }
	static inline value_type& xresolve(IterableType &a, typename IterableType::iterator it)
		{ return a.resolve_iterator(it); }
};
template<typename T>
struct citerator<vector<T> >
{
	static inline const T& resolve(const vector<T> &a, typename vector<T>::const_iterator it)
		{ return *it; }
};
template<>
struct citerator<string>
{
	static inline char resolve(const string &a, gcc_typename string::const_iterator it)
		{ return *it; }
};
template<typename T>
struct _seq
{
    template<typename F>
    static inline void process(T &t, F f) { t.process(f); }
};
template<typename T>
struct _seq<const T>
{
	template<typename F>
	static inline void process(const T &t, F f) { t.process(f); }
};
template<typename T>
struct _seq<vector<T> >
{
    template<typename F>
    static void process(vector<T> &t, F f)
    {
        for (typename vector<T>::iterator it = t.begin(); it != t.end(); ++it)
            if (!f(*it)) break;
    }
};
template<typename T>
struct _seq<const vector<T> >
{
    template<typename F>
    static void process(const vector<T> &t, F f)
    {
        for (typename vector<T>::const_iterator it = t.begin(); it != t.end(); ++it)
            if (!f(*it)) break;
    }
};
template<>
struct _seq<string>
{
    template<typename F>
    static void process(string &s, F f)
    {
        for (size_t i = 0; i < s.length(); i++)
            if (!f(s[i])) break;
    }
};
template<>
struct _seq<const string>
{
    template<typename F>
    static void process(const string &s, F f)
    {
        for (size_t i = 0; i < s.length(); i++)
            if (!f(s[i])) break;
    }
};
template<typename T, typename F>
inline void _seq_process_c(const T &t, F f)
{
	_seq<const T>::template process<F>(t, f);
}
#define xbreak return false
#define xforeach_(a, v) \
    _seq_process_c(a, [&](const gcc_typename ValueType<decltype(a)>::type &v) -> bool {
#define xforeachi_(a, i, v) \
    { \
    typedef const gcc_typename ValueType<decltype(a)>::type &_T_; \
    int i = -1; \
    _seq_process_c(a, [&](_T_ v) -> bool { ++i; return [&]() -> bool {
#define x_endfe return true; });
#define x_endfei return true; }(); }); }
#define xforeach(a, v, ...)  xforeach_(a, v) __VA_ARGS__; x_endfe
#define xforeachi(a, i, v, ...) xforeachi_(a, i, v) __VA_ARGS__; x_endfei
#define xfor(a, v, ...) xforeach(a, v, __VA_ARGS__)
struct SepSpace { inline static void Print() { _wsp; } };
struct SepComma { inline static void Print() { _wstr(", "); } };
static char __strbuf[1000001];
template<typename T>
struct _io
{
	inline static void read(T &x, int i) { x._read(i); }
	inline static void write(const T &x) { x._write(); }
};
template<>
struct _io<int>
{
	inline static void read(int &x, int i) { scanf("%d", &x); }
	inline static void write(const int &x) { printf("%d", x); }
};
template<>
struct _io<int&>
{
	inline static void read(int &x, int i) { scanf("%d", &x); }
	inline static void write(const int &x) { printf("%d", x); }
};
template<>
struct _io<const int&>
{
	inline static void write(const int &x) { printf("%d", x); }
};
template<>
struct _io<long long>
{
	inline static void read(long long &x, int i) { scanf(LL_SPEC, &x); }
	inline static void write(const long long &x) { printf(LL_SPEC, x); }
};
template<>
struct _io<long long&>
{
	inline static void read(long long &x, int i) { scanf(LL_SPEC, &x); }
	inline static void write(const long long &x) { printf(LL_SPEC, x); }
};
template<>
struct _io<double>
{
	inline static void read(double &x, int i) { scanf("%lf", &x); }
	inline static void write(const double &x) { printf("%.9lf", x); }
};
template<>
struct _io<const double>
{
	inline static void write(const double &x) { printf("%.9lf", x); }
};
template<>
struct _io<double&>
{
	inline static void read(double &x, int i) { scanf("%lf", &x); }
	inline static void write(const double &x) { printf("%.9lf", x); }
};
template<>
struct _io<char>
{
	inline static void read(char &c, int i) { char buf[3]; scanf("%s", buf); c = buf[0]; }
	inline static void write(const char &c) { printf("%c", c); }
};
template<>
struct _io<bool>
{
	inline static void read(bool &b, int i) { int t; scanf("%d", &t); b = t != 0; }
	inline static void write(const bool &b) { printf("%s", b ? "#t" : "#f"); }
};
template<>
struct _io<string>
{
    inline static void read(string &s, int i) { scanf("%s", __strbuf); s = string(__strbuf); }
    inline static void write(const string &s) { printf("%s", s.c_str()); }
};
template<typename T> inline void _w(const T &a) { _io<T>::write(a); }
#define _w_(x) _w(x); _wlf
template<typename T>
struct Idx2
{
    T i, j;
    Idx2(T i, T j) : i(i), j(j) {}
    Idx2() : i(-1), j(-1) {}
    inline void _write() const { _wstr("("); _io<T>::write(i); _wstr(", "); _io<T>::write(j); _wstr(")"); }
    inline void _read(int idx) { _io<T>::read(i, idx); _io<T>::read(j, idx); }
	inline bool operator == (const Idx2<T> &other) const { return i == other.i && j == other.j; }
	inline bool operator < (const Idx2<T> &other) const { return cmp_aa(i, j); }
};
template<typename T>
struct _null<Idx2<T> > { inline static Idx2<T> value() { return Idx2<T>(-1, -1); } };
template<typename T>
struct cmap
{
};
template<typename Y>
struct cmap<Y**>
{
	typedef Idx2<int> key_type;
	inline static void write(Y **a, key_type i, const Y &value) { a[i.i][i.j] = value; }
	inline static Y& read(Y **a, key_type i) { return a[i.i][i.j]; }
};
template<typename Y>
struct cmap<Y**&>
{
	typedef Idx2<int> key_type;
	inline static void write(Y **&a, key_type i, const Y &value) { a[i.i][i.j] = value; }
	inline static Y& read(Y **&a, key_type i) { return a[i.i][i.j]; }
};
template<typename Y, int sz>
struct cmap<Y [sz]>
{
	typedef int key_type;
	inline static void write(Y a[sz], int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y a[sz], int i) { return a[i]; }
};
template<typename Y, int sz>
struct cmap<Y (&)[sz]>
{
	typedef int key_type;
	inline static void write(Y (&a)[sz], int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y (&a)[sz], int i) { return a[i]; }
};
template<typename Y>
struct cmap<Y*>
{
	typedef int key_type;
	inline static void write(Y *a, int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y *a, int i) { return a[i]; }
};
template<typename Y>
struct cmap<Y*&>
{
	typedef int key_type;
	inline static void write(Y *&a, int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y *&a, int i) { return a[i]; }
};
template<typename T>
struct iterable_wrap
{
	SEQ_TYPE(T) base;
    iterable_wrap(const T &base) : base(base) {}
    typedef T value_type;
    template<typename F>
    inline void process(F f) const { f(base); }
	inline int size() const { return 1; }
};
template<typename T>
inline iterable_wrap<T> IW(const T &x) { return iterable_wrap<T>(x); }
#define $I(type, name) \
	type name; \
	_io<type>::read(name, 0)
#define $I2(type, name1, name2) $I(type, name1); $I(type, name2)
#define _inx(type, name, sz) \
	type *name; \
	name = new type[sz]; \
	for (int __i = 0; __i < sz; __i++) _io<type>::read(name[__i], __i);
#define _tmpx(type, name, sz) \
	type *name; \
	name = new type[sz];
template<typename T, typename sep>
void write_array(const T &a, int n)
{
	typedef typename item_type<T>::type X;
	for (int i = 0; i + 1 < n; i++)
	{
		_io<X>::write(a[i]);
		sep::Print();
	}
	if (n > 0) _io<X>::write(a[n-1]);
}
template<typename T, typename Sep>
void write_iterable(const T &a, Sep sep)
{
	bool first = true;
    typedef typename T::value_type i_type;
	xforeach(a, i,
		if (!first) sep.Print();
		_io<i_type>::write(i);
		first = false;
	)
}
template<typename T>
struct _io<vector<T> >
{
	inline static void read(vector<T> &x, int idx)
    {
        int sz;
        _io<int>::read(sz, 0);
        assert(sz >= 0);
        x.resize(sz);
        for (int i = 0; i < sz; i++) _io<T>::read(x[i], i);
    }
	inline static void write(const vector<T> &x) { _wstr("["); write_array<vector<T>, SepComma>(x, x.size()); _wstr("]"); }
};
#define _wi(a) write_iterable(a, SepSpace())
struct tup0 {
	inline void _read(int i) {}
	inline void __write() const { _wstr("("); }
	inline void _write() const { __write(); _wstr(")"); }
};
struct tup0i {
	int idx;
	inline void _read(int i) { idx = i; }
	inline void __write() const { _wstr("(idx: "); _io<int>::write(idx); }
	inline void _write() const { __write(); _wstr(")"); }
};
template<typename T>
struct _is_empty { enum { value = 0 }; };
template<>
struct _is_empty<tup0> { enum { value = 1 }; };
#define extend_fieldr(name, base, type, field_name) \
	struct name : public base \
	{ \
		type field_name; \
		typedef type field_name##_type; \
		name() {} \
		inline void __write() const { base::__write(); if (!_is_empty<base>::value) _wsp; \
			_wstr(#field_name ":"); _io<type>::write(field_name); } \
		inline void _write() const { __write(); _wstr(")"); } \
		inline void _read(int i) { base::_read(i); _io<type>::read(field_name, i); }
#define _end_extend }
#define _CMP_(name, cmp) bool operator < (const name &other) const { return cmp; }
#define tup1(name, t1, name1) tup1c(name, t1, name1, false)
#define tup1c(name, t1, name1, cmp) \
	extend_fieldr(name, tup0, t1, name1) \
		name(t1 name1) : name1(name1) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup1i(name, t1, name1) tup1ic(name, t1, name1, false)
#define tup1ic(name, t1, name1, cmp) \
	extend_fieldr(name, tup0i, t1, name1) \
		name(t1 name1) : name1(name1) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup2(name, t1, name1, t2, name2) tup2c(name, t1, name1, t2, name2, false)
#define tup2c(name, t1, name1, t2, name2, cmp) tup2c_(STRUCT_NAME, name, t1, name1, t2, name2, cmp)
#define tup2c_(bname, name, t1, name1, t2, name2, cmp) \
	tup1(bname, t1, name1); \
	extend_fieldr(name, bname, t2, name2) \
		name(t1 name1, t2 name2) : bname(name1), name2(name2) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup2i(name, t1, name1, t2, name2) tup2ic(name, t1, name1, t2, name2, false)
#define tup2ic(name, t1, name1, t2, name2, cmp) tup2ic_(STRUCT_NAME, name, t1, name1, t2, name2, cmp)
#define tup2ic_(bname, name, t1, name1, t2, name2, cmp) \
	tup1i(bname, t1, name1); \
	extend_fieldr(name, bname, t2, name2) \
		name(t1 name1, t2 name2) : bname(name1), name2(name2) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup3(name, t1, name1, t2, name2, t3, name3) tup3_(STRUCT_NAME, name, t1, name1, t2, name2, t3, name3)
#define tup3_(bname, name, t1, name1, t2, name2, t3, name3) \
	tup2(bname, t1, name1, t2, name2); \
	extend_fieldr(name, bname, t3, name3) \
		name(t1 name1, t2 name2, t3 name3) : bname(name1, name2), name3(name3) {} \
	_end_extend
#define seqarr(name, a) \
	const auto &name##_tmp = a; \
	$Tx(ValueType<decltype(name##_tmp)>::type, name, xlen(name##_tmp)); \
	xforeachi(name##_tmp, i, x, name[i] = x);
#define _sortf(a, ftr) if (a.size() > 0) \
	sort(&a[0], &a[0] + a.size(), \
	[](const ValueType<decltype(a)>::type &_1, const ValueType<decltype(a)>::type & _2) -> bool { return ftr; })
#define $$ auto
template<typename T>
int xlen(const T &a) { return (int)a.size(); }
template<typename T>
struct key_type { typedef int type; };
template<typename ArrType>
struct ArrWrapper
{
	typedef ArrType base_type;
	ArrType &a;
	int n;
	ArrWrapper(ArrType &a, int n) : a(a), n(n) {}
	typedef typename item_type<ArrType>::type value_type;
	typedef int iterator;
	inline iterator begin() const { return 0; }
	inline iterator end() const { return n; }
	inline int size() const { return n; }
	inline value_type& resolve_iterator(const iterator &it) const
	{
		return cmap<ArrType>::read(a, it);
	}
	inline value_type& operator [] (int i) { return a[i]; }
	void erase(int p)
	{
		assert(p < n);
		for (int i = p + 1; i < n; ++i) a[i-1] = a[i];
		--n;
	}
    template<typename F>
    void process(F f) const
    {
        for (int i = 0; i < n; i++)
            if (!f(a[i])) break;
    }
	ITER_WRITE
};
template<typename T>
struct cmap<ArrWrapper<T> >
{
	typedef typename ArrWrapper<T>::value_type V;
	inline static void write(ArrWrapper<T> &a, int i,
		const V value) { a.a[i] = value; }
	inline static V& read(ArrWrapper<T> &a, int i) { return a.a[i]; }
};
#define _wrap(name, base, n) \
	ArrWrapper<decltype(base)> name(base, n)
#define $Ix(type, name, n) \
	_inx(type, name##_base, n); \
	_wrap(name, name##_base, n)
#define $Tx(type, name, n) \
	_tmpx(type, name##_base, n); \
	_wrap(name, name##_base, n)
template<typename InIterable, typename S, typename F>
struct FoldWrapper
{
	SEQ_TYPE(InIterable) a;
	typedef S value_type;
	typedef FoldWrapper<InIterable, S, F> my_type;
	S init_val;
	F f;
	FoldWrapper(const InIterable &a, const S &init_val, F f) : a(a), init_val(init_val), f(f) {}
	typedef typename InIterable::iterator base_iterator;
	typedef typename InIterable::value_type base_value_type;
	tup3(_iterator, base_iterator, it, S, val, const my_type&, owner);
	struct iterator : public _iterator
	{
		iterator(const base_iterator &it, const S &val, const my_type &owner) : _iterator(it, val, owner) {}
		inline bool operator != (const iterator &other) const { return _iterator::it != other.it; }
		inline iterator& operator ++ () { _iterator::val = _iterator::owner.f(citerator<InIterable>::resolve(_iterator::owner.a, _iterator::it), _iterator::val); ++_iterator::it; return *this; }
	};
	inline iterator begin() const { return iterator(a.begin(), init_val, *this); }
	inline iterator end() const { return iterator(a.end(), _null<S>::value(), *this); }
	inline int size() const { return a.size(); }
	inline S resolve_iterator(const iterator &it) const
	{
		return f(citerator<InIterable>::resolve(a, it.it), it.val);
	}
    template<typename Ftr> inline
    void process(Ftr ftr) const
    {
        S cur = init_val;
        xforeach(a, x,
            cur = f(x, cur);
            if (!ftr(cur)) xbreak;
        )
    }
	ITER_WRITE
};
template<typename T, typename S, typename F> inline
FoldWrapper<T, S, F> create_fold_wrapper(const T &a, const S &init_val, F f)
{
    return FoldWrapper<T, S, F>(a, init_val, f);
}
#define _fold(name, a0, ftr, seq) \
	create_fold_wrapper(seq, a0, [&](const gcc_typename ValueType<decltype(seq)>::type &_, const decltype(a0) &name) { return ftr; })
template<typename T1, typename T2>
struct _pair
{
    tup2(type, T1, f, T2, s);
};
template<typename T1, typename T2>
typename _pair<T1, T2>::type PAIR(const T1 &f, const T2 &s)
{
	return typename _pair<T1, T2>::type(f, s);
}
template<typename T, typename F, typename S>
struct MapWrapper
{
	SEQ_TYPE(T) a;
	typedef S value_type;
	F f;
	MapWrapper(const T &a, F f) : a(a), f(f) {}
	typedef typename T::iterator iterator;
	inline iterator begin() const { return a.begin(); }
	inline iterator end() const { return a.end(); }
	inline int size() const { return a.size(); }
	inline S resolve_iterator(const iterator &it) const
	{
		return f(citerator<T>::resolve(a, it));
	}
    template<typename Ftr>
    inline void process(Ftr ftr) const
    {
        xforeach(a, x,
            if (!ftr(f(x))) xbreak
        );
    }
	ITER_WRITE
};
template<typename T, typename F>
auto SimpleMapWrapper(const T &a, F f) -> MapWrapper<T, F, decltype(f( gcc_typename ValueType<T>::type() ))>
{
	return MapWrapper<T, F, decltype(f( gcc_typename ValueType<T>::type() ))>(a, f);
}
#define _map(a, ...) SimpleMapWrapper(a, [&](const ValueType<decltype(a)>::type &_) \
	 { return __VA_ARGS__; })
template<
	typename T,
	typename Filter
>
struct FilterWrapper
{
	SEQ_TYPE(T) a;
	Filter filter;
	FilterWrapper(const T &a, Filter filter) : a(a), filter(filter) {}
	typedef typename T::value_type value_type;
	typedef _DummyType iterator;
	template<typename F>
	inline void process(F f) const
	{
		xforeach(a, x,
			if (filter(x))
				if (!f(x)) xbreak
		)
	}
    inline int size() const { return _count(*this); }
	ITER_WRITE
};
template<typename T, typename Filter>
inline FilterWrapper<T, Filter> CreateFilterWrapper(const T &t, Filter f)
{
	return FilterWrapper<T, Filter>(t, f);
}
#define _filter(cond, a) \
	CreateFilterWrapper(a, [&](const ValueType<decltype(a)>::type &_) -> bool { return cond; })
template<
    typename T
>
struct TakeWrapper
{
    SEQ_TYPE(T) a;
    int cnt;
    TakeWrapper(int cnt, const T &a) : cnt(cnt), a(a) { assert(cnt >= 0); }
    typedef typename T::value_type value_type;
    template<typename F>
    inline void process(F f) const
    {
		if (cnt <= 0) return;
        int i = 0;
        xforeach(a, x,
            if (!f(x)) xbreak;
			++i;
			if (i >= cnt) xbreak;
        )
    }
    inline int size() const { return min(cnt, (int)a.size()); }
    typedef _DummyType iterator;
	ITER_WRITE
};
template<typename T>
inline TakeWrapper<T> _take(int cnt, const T &a)
{
    return TakeWrapper<T>(cnt, a);
}
template<typename T1, typename T2>
struct ConcatLists
{
    typedef typename T1::value_type value_type;
    SEQ_TYPE(T1) a;
    SEQ_TYPE(T2) b;
    ConcatLists(const T1 &a, const T2 &b) : a(a), b(b) {}
    template<typename F>
    inline void process(F f) const
    {
		bool stop = false;
		xforeach(a, i, if (!f(i)) { stop = true; xbreak; } )
        if (!stop) xforeach(b, i, if (!f(i)) xbreak )
    }
    inline int size() const { return a.size() + b.size(); }
	typedef _DummyType iterator;
	ITER_WRITE
};
template<typename T>
struct __lcat
{
	const T &a;
	__lcat(const T &a) : a(a) {}
	template<typename T2> inline
		ConcatLists<T, T2> operator % (const T2 &b) const { return ConcatLists<T, T2>(a, b); }
};
struct _lcat {};
template<typename T> inline
	__lcat<T> operator % (const T &a, _lcat) { return __lcat<T>(a); }
#define lcat _lcat() %
template<typename T>
inline int _count(const T &a)
{
    int res = 0;
    xforeach(a, i, ++res);
    return res;
}
template<
	typename T,
	typename S,
	typename StopFtr,
	typename GenFtr,
	typename TransformFtr
>
struct GenWrapper
{
	T a0;
	StopFtr stop_ftr;
	GenFtr gen_ftr;
	TransformFtr transform_ftr;
	typedef S value_type;
	GenWrapper(const T &a0, StopFtr stop_ftr, GenFtr gen_ftr, TransformFtr transform_ftr)
		: a0(a0), stop_ftr(stop_ftr), gen_ftr(gen_ftr), transform_ftr(transform_ftr) {}
	template<typename F>
	inline void process(F f) const
	{
		T cur = a0;
		while (stop_ftr(cur))
		{
			if (!f(gen_ftr(cur))) return;
			cur = transform_ftr(cur);
		}
	}
	inline int size() const { return _count(*this); }
    typedef _DummyType iterator;
	ITER_WRITE
};
template<
	typename T,
	typename StopFtr,
	typename GenFtr,
	typename TransformFtr
>
inline auto create_gen(const T &a0, StopFtr stop_ftr, GenFtr gen_ftr, TransformFtr transform_ftr) ->
GenWrapper<T, decltype(gen_ftr(T())), StopFtr, GenFtr, TransformFtr>
{
	return GenWrapper<T, decltype(gen_ftr(T())), StopFtr, GenFtr, TransformFtr>(a0, stop_ftr, gen_ftr, transform_ftr);
}
#define _gen(name, a0, stop_ftr, gen_ftr, transform_ftr) \
	create_gen(a0, [&](const decltype(a0) &name) -> bool { return stop_ftr; }, \
				   [&](const decltype(a0) &name) { return gen_ftr; }, \
				   [&](const decltype(a0) &name) -> decltype(a0) { return transform_ftr; })
template<typename T, typename F>
inline typename T::value_type _Collapse(const T &a, F f)
{
	typedef typename T::value_type S;
	S res;
	bool first = true;
	xfor(a, x,
		if (first)
		{
			res = x;
			first = false;
		}
		else
		{
			res = f(x, res);
		}
	);
	return res;
}
#define _collapse(name, ftr, seq) \
	_Collapse(seq, [&](const gcc_typename ValueType<decltype(seq)>::type &_, const gcc_typename ValueType<decltype(seq)>::type &name) { return ftr; })
#ifndef ONLINE_JUDGE
#define _open_files(name) freopen(name ".in", "r", stdin); freopen(name ".out", "w", stdout)
#else
#define _open_files(name)
#endif
#define _END_SOL int main() { _open_files("test"); solve(); return 0; }
_SOLUTION


#define _SOLUTION                                                                                \
                                                                                \
                                                                                \
                                                                                \
                                                                                \
void solve() {                                                                                \
    $I2(int, n, v);                                                                                \
    tup2i(X, int, t, int, p);                                                                      \
    $Ix(X, vehicles, n);                                                                           \
                                                                                \
    seqvec(kayaks, _filter(_.t == 1, vehicles));                                                   \
    seqvec(cats, _filter(_.t == 2, vehicles));                                                     \
                                                                                \
    _sortf(kayaks, Lcmp_d(p));                                                                     \
    _sortf(cats, Lcmp_d(p));                                                                       \
                                                                                \
    seqvec(a1, IW(0) %lcat _fold(x, 0, x + _.p, cats));                                            \
    seqvec(a2, IW(0) %lcat _fold(x, 0, x + _.p, kayaks));                                          \
                                                                                \
    $$ ways = _gen(x, 0, 2*x <= v && x <= xlen(cats), PAIR(x, min(v - 2*x, xlen(kayaks))), x + 1); \
    $$ ways2 = _map(ways, PAIR(_, a1[_.f] + a2[_.s]));                                             \
    $$ res = _collapse(x, _.s > x.s ? _ : x, ways2);                                               \
                                                                                \
    $$ idxs = _map(_take(res.f.f, cats) %lcat _take(res.f.s, kayaks), _.idx + 1);                  \
                                                                                \
    _w_(res.s);                                                                                \
    _wi(idxs);                                                                                \
}                                                                                \
                                                                                \
_END_SOL                                                                                \
                                                                                \
                                                                                \
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ====== <<< PREWRITTEN CODE >>> ============================================
//
#pragma comment(linker, "/STACK:32000000")
#define _CRT_SECURE_NO_DEPRECATE
#include <sstream>
#include <iostream>
#include <string>
#include <algorithm>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <stdarg.h>
#include <memory.h>
#include <string.h>
#include <assert.h>
#include <type_traits>
#include <limits>
#include <hash_map>
#include <hash_set>
using namespace std;
#define gcc_typename typename
using namespace __gnu_cxx;
#define LL_SPEC "%I64d"
#define ITER_WRITE inline void _write() const { _wstr("["); write_iterable(*this, SepComma()); _wstr("]"); }
#define SEQ_TYPE(x) const x
#define FUNC2(x,y) x##y
#define FUNC1(x,y) FUNC2(x,y)
#define FUNC(x) FUNC1(x,__COUNTER__)
#define STRUCT_NAME FUNC(struct_)
struct _DummyType {};
template<typename T>
struct ValueType {
	typedef typename remove_reference<T>::type clean_type;
	typedef typename clean_type::value_type type;
};
#define _wsp printf(" ")
#define _wlf printf("\n")
#define _wstr(s) printf("%s", s)
#define cmp_a(a) a < other.a
#define cmp_aa(a, b) cmp_a(a) || (a == other.a && b < other.b)
#define Lcmp_d(a) _1.a > _2.a
template<typename T>
struct item_type { typedef typename T::value_type type; };
template<typename T>
struct item_type<T*> { typedef T type; };
template<typename T, size_t sz>
struct item_type<T[sz]> { typedef T type; };
template<typename T, size_t sz>
struct item_type<T(&)[sz]> { typedef T type; };
template<typename T>
struct item_type<T*&> { typedef T type; };
template<typename T>
struct item_type<T**> { typedef T type; };
template<typename T>
struct item_type<T**&> { typedef T type; };
template<typename T>
struct _null { inline static T value() { return T(-1); } };
template<typename IterableType>
struct citerator
{
	typedef typename IterableType::value_type value_type;
	static inline value_type resolve(const IterableType &a, typename IterableType::iterator it)
		{ return a.resolve_iterator(it); }
	static inline value_type& xresolve(IterableType &a, typename IterableType::iterator it)
		{ return a.resolve_iterator(it); }
};
template<typename T>
struct citerator<vector<T> >
{
	static inline const T& resolve(const vector<T> &a, typename vector<T>::const_iterator it)
		{ return *it; }
};
template<>
struct citerator<string>
{
	static inline char resolve(const string &a, gcc_typename string::const_iterator it)
		{ return *it; }
};
template<typename T>
struct _seq
{
    template<typename F>
    static inline void process(T &t, F f) { t.process(f); }
};
template<typename T>
struct _seq<const T>
{
	template<typename F>
	static inline void process(const T &t, F f) { t.process(f); }
};
template<typename T>
struct _seq<vector<T> >
{
    template<typename F>
    static void process(vector<T> &t, F f)
    {
        for (typename vector<T>::iterator it = t.begin(); it != t.end(); ++it)
            if (!f(*it)) break;
    }
};
template<typename T>
struct _seq<const vector<T> >
{
    template<typename F>
    static void process(const vector<T> &t, F f)
    {
        for (typename vector<T>::const_iterator it = t.begin(); it != t.end(); ++it)
            if (!f(*it)) break;
    }
};
template<>
struct _seq<string>
{
    template<typename F>
    static void process(string &s, F f)
    {
        for (size_t i = 0; i < s.length(); i++)
            if (!f(s[i])) break;
    }
};
template<>
struct _seq<const string>
{
    template<typename F>
    static void process(const string &s, F f)
    {
        for (size_t i = 0; i < s.length(); i++)
            if (!f(s[i])) break;
    }
};
template<typename T, typename F>
inline void _seq_process_c(const T &t, F f)
{
	_seq<const T>::template process<F>(t, f);
}
#define xbreak return false
#define xforeach_(a, v) \
    _seq_process_c(a, [&](const gcc_typename ValueType<decltype(a)>::type &v) -> bool {
#define x_endfe return true; });
#define xforeach(a, v, ...)  xforeach_(a, v) __VA_ARGS__; x_endfe
#define xfor(a, v, ...) xforeach(a, v, __VA_ARGS__)
struct SepSpace { inline static void Print() { _wsp; } };
struct SepComma { inline static void Print() { _wstr(", "); } };
static char __strbuf[1000001];
template<typename T>
struct _io
{
	inline static void read(T &x, int i) { x._read(i); }
	inline static void write(const T &x) { x._write(); }
};
template<>
struct _io<int>
{
	inline static void read(int &x, int i) { scanf("%d", &x); }
	inline static void write(const int &x) { printf("%d", x); }
};
template<>
struct _io<int&>
{
	inline static void read(int &x, int i) { scanf("%d", &x); }
	inline static void write(const int &x) { printf("%d", x); }
};
template<>
struct _io<const int&>
{
	inline static void write(const int &x) { printf("%d", x); }
};
template<>
struct _io<long long>
{
	inline static void read(long long &x, int i) { scanf(LL_SPEC, &x); }
	inline static void write(const long long &x) { printf(LL_SPEC, x); }
};
template<>
struct _io<long long&>
{
	inline static void read(long long &x, int i) { scanf(LL_SPEC, &x); }
	inline static void write(const long long &x) { printf(LL_SPEC, x); }
};
template<>
struct _io<double>
{
	inline static void read(double &x, int i) { scanf("%lf", &x); }
	inline static void write(const double &x) { printf("%.9lf", x); }
};
template<>
struct _io<const double>
{
	inline static void write(const double &x) { printf("%.9lf", x); }
};
template<>
struct _io<double&>
{
	inline static void read(double &x, int i) { scanf("%lf", &x); }
	inline static void write(const double &x) { printf("%.9lf", x); }
};
template<>
struct _io<char>
{
	inline static void read(char &c, int i) { char buf[3]; scanf("%s", buf); c = buf[0]; }
	inline static void write(const char &c) { printf("%c", c); }
};
template<>
struct _io<bool>
{
	inline static void read(bool &b, int i) { int t; scanf("%d", &t); b = t != 0; }
	inline static void write(const bool &b) { printf("%s", b ? "#t" : "#f"); }
};
template<>
struct _io<string>
{
    inline static void read(string &s, int i) { scanf("%s", __strbuf); s = string(__strbuf); }
    inline static void write(const string &s) { printf("%s", s.c_str()); }
};
template<typename T> inline void _w(const T &a) { _io<T>::write(a); }
#define _w_(x) _w(x); _wlf
template<typename T>
struct Idx2
{
    T i, j;
    Idx2(T i, T j) : i(i), j(j) {}
    Idx2() : i(-1), j(-1) {}
    inline void _write() const { _wstr("("); _io<T>::write(i); _wstr(", "); _io<T>::write(j); _wstr(")"); }
    inline void _read(int idx) { _io<T>::read(i, idx); _io<T>::read(j, idx); }
	inline bool operator == (const Idx2<T> &other) const { return i == other.i && j == other.j; }
	inline bool operator < (const Idx2<T> &other) const { return cmp_aa(i, j); }
};
template<typename T>
struct _null<Idx2<T> > { inline static Idx2<T> value() { return Idx2<T>(-1, -1); } };
template<typename T>
struct cmap
{
};
template<typename Y>
struct cmap<Y**>
{
	typedef Idx2<int> key_type;
	inline static void write(Y **a, key_type i, const Y &value) { a[i.i][i.j] = value; }
	inline static Y& read(Y **a, key_type i) { return a[i.i][i.j]; }
};
template<typename Y>
struct cmap<Y**&>
{
	typedef Idx2<int> key_type;
	inline static void write(Y **&a, key_type i, const Y &value) { a[i.i][i.j] = value; }
	inline static Y& read(Y **&a, key_type i) { return a[i.i][i.j]; }
};
template<typename Y, int sz>
struct cmap<Y [sz]>
{
	typedef int key_type;
	inline static void write(Y a[sz], int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y a[sz], int i) { return a[i]; }
};
template<typename Y, int sz>
struct cmap<Y (&)[sz]>
{
	typedef int key_type;
	inline static void write(Y (&a)[sz], int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y (&a)[sz], int i) { return a[i]; }
};
template<typename Y>
struct cmap<Y*>
{
	typedef int key_type;
	inline static void write(Y *a, int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y *a, int i) { return a[i]; }
};
template<typename Y>
struct cmap<Y*&>
{
	typedef int key_type;
	inline static void write(Y *&a, int i, const Y &value) { a[i] = value; }
	inline static Y& read(Y *&a, int i) { return a[i]; }
};
template<typename T>
struct iterable_wrap
{
	SEQ_TYPE(T) base;
    iterable_wrap(const T &base) : base(base) {}
    typedef T value_type;
    template<typename F>
    inline void process(F f) const { f(base); }
};
template<typename T>
inline iterable_wrap<T> IW(const T &x) { return iterable_wrap<T>(x); }
#define $I(type, name) \
	type name; \
	_io<type>::read(name, 0)
#define $I2(type, name1, name2) $I(type, name1); $I(type, name2)
#define _inx(type, name, sz) \
	type *name; \
	name = new type[sz]; \
	for (int __i = 0; __i < sz; __i++) _io<type>::read(name[__i], __i);
template<typename T, typename sep>
void write_array(const T &a, int n)
{
	typedef typename item_type<T>::type X;
	for (int i = 0; i + 1 < n; i++)
	{
		_io<X>::write(a[i]);
		sep::Print();
	}
	if (n > 0) _io<X>::write(a[n-1]);
}
template<typename T, typename Sep>
void write_iterable(const T &a, Sep sep)
{
	bool first = true;
    typedef typename T::value_type i_type;
	xforeach(a, i,
		if (!first) sep.Print();
		_io<i_type>::write(i);
		first = false;
	)
}
template<typename T>
struct _io<vector<T> >
{
	inline static void read(vector<T> &x, int idx)
    {
        int sz;
        _io<int>::read(sz, 0);
        assert(sz >= 0);
        x.resize(sz);
        for (int i = 0; i < sz; i++) _io<T>::read(x[i], i);
    }
	inline static void write(const vector<T> &x) { _wstr("["); write_array<vector<T>, SepComma>(x, x.size()); _wstr("]"); }
};
#define _wi(a) write_iterable(a, SepSpace())
struct tup0 {
	inline void _read(int i) {}
	inline void __write() const { _wstr("("); }
	inline void _write() const { __write(); _wstr(")"); }
};
struct tup0i {
	int idx;
	inline void _read(int i) { idx = i; }
	inline void __write() const { _wstr("(idx: "); _io<int>::write(idx); }
	inline void _write() const { __write(); _wstr(")"); }
};
template<typename T>
struct _is_empty { enum { value = 0 }; };
template<>
struct _is_empty<tup0> { enum { value = 1 }; };
#define extend_fieldr(name, base, type, field_name) \
	struct name : public base \
	{ \
		type field_name; \
		typedef type field_name##_type; \
		name() {} \
		inline void __write() const { base::__write(); if (!_is_empty<base>::value) _wsp; \
			_wstr(#field_name ":"); _io<type>::write(field_name); } \
		inline void _write() const { __write(); _wstr(")"); } \
		inline void _read(int i) { base::_read(i); _io<type>::read(field_name, i); }
#define _end_extend }
#define _CMP_(name, cmp) bool operator < (const name &other) const { return cmp; }
#define tup1(name, t1, name1) tup1c(name, t1, name1, false)
#define tup1c(name, t1, name1, cmp) \
	extend_fieldr(name, tup0, t1, name1) \
		name(t1 name1) : name1(name1) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup1i(name, t1, name1) tup1ic(name, t1, name1, false)
#define tup1ic(name, t1, name1, cmp) \
	extend_fieldr(name, tup0i, t1, name1) \
		name(t1 name1) : name1(name1) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup2(name, t1, name1, t2, name2) tup2c(name, t1, name1, t2, name2, false)
#define tup2c(name, t1, name1, t2, name2, cmp) tup2c_(STRUCT_NAME, name, t1, name1, t2, name2, cmp)
#define tup2c_(bname, name, t1, name1, t2, name2, cmp) \
	tup1(bname, t1, name1); \
	extend_fieldr(name, bname, t2, name2) \
		name(t1 name1, t2 name2) : bname(name1), name2(name2) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup2i(name, t1, name1, t2, name2) tup2ic(name, t1, name1, t2, name2, false)
#define tup2ic(name, t1, name1, t2, name2, cmp) tup2ic_(STRUCT_NAME, name, t1, name1, t2, name2, cmp)
#define tup2ic_(bname, name, t1, name1, t2, name2, cmp) \
	tup1i(bname, t1, name1); \
	extend_fieldr(name, bname, t2, name2) \
		name(t1 name1, t2 name2) : bname(name1), name2(name2) {} \
		_CMP_(name, cmp) \
	_end_extend
#define tup3(name, t1, name1, t2, name2, t3, name3) tup3_(STRUCT_NAME, name, t1, name1, t2, name2, t3, name3)
#define tup3_(bname, name, t1, name1, t2, name2, t3, name3) \
	tup2(bname, t1, name1, t2, name2); \
	extend_fieldr(name, bname, t3, name3) \
		name(t1 name1, t2 name2, t3 name3) : bname(name1, name2), name3(name3) {} \
	_end_extend
#define seqvec(name, a) \
	const auto &name##_tmp = a; \
	vector<ValueType<decltype(name##_tmp)>::type> name; \
	populate(name, name##_tmp)
#define _sortf(a, ftr) if (a.size() > 0) \
	sort(&a[0], &a[0] + a.size(), \
	[](const ValueType<decltype(a)>::type &_1, const ValueType<decltype(a)>::type & _2) -> bool { return ftr; })
#define $$ auto
template<typename T>
int xlen(const T &a) { return (int)a.size(); }
template<typename T>
struct key_type { typedef int type; };
template<typename ArrType>
struct ArrWrapper
{
	typedef ArrType base_type;
	ArrType &a;
	int n;
	ArrWrapper(ArrType &a, int n) : a(a), n(n) {}
	typedef typename item_type<ArrType>::type value_type;
	typedef int iterator;
	inline iterator begin() const { return 0; }
	inline iterator end() const { return n; }
	inline int size() const { return n; }
	inline value_type& resolve_iterator(const iterator &it) const
	{
		return cmap<ArrType>::read(a, it);
	}
	inline value_type& operator [] (int i) { return a[i]; }
	void erase(int p)
	{
		assert(p < n);
		for (int i = p + 1; i < n; ++i) a[i-1] = a[i];
		--n;
	}
    template<typename F>
    void process(F f) const
    {
        for (int i = 0; i < n; i++)
            if (!f(a[i])) break;
    }
	ITER_WRITE
};
template<typename T>
struct cmap<ArrWrapper<T> >
{
	typedef typename ArrWrapper<T>::value_type V;
	inline static void write(ArrWrapper<T> &a, int i,
		const V value) { a.a[i] = value; }
	inline static V& read(ArrWrapper<T> &a, int i) { return a.a[i]; }
};
#define _wrap(name, base, n) \
	ArrWrapper<decltype(base)> name(base, n)
#define $Ix(type, name, n) \
	_inx(type, name##_base, n); \
	_wrap(name, name##_base, n)
template<typename InIterable, typename S, typename F>
struct FoldWrapper
{
	SEQ_TYPE(InIterable) a;
	typedef S value_type;
	typedef FoldWrapper<InIterable, S, F> my_type;
	S init_val;
	F f;
	FoldWrapper(const InIterable &a, const S &init_val, F f) : a(a), init_val(init_val), f(f) {}
	typedef typename InIterable::iterator base_iterator;
	typedef typename InIterable::value_type base_value_type;
	tup3(_iterator, base_iterator, it, S, val, const my_type&, owner);
	struct iterator : public _iterator
	{
		iterator(const base_iterator &it, const S &val, const my_type &owner) : _iterator(it, val, owner) {}
		inline bool operator != (const iterator &other) const { return _iterator::it != other.it; }
		inline iterator& operator ++ () { _iterator::val = _iterator::owner.f(citerator<InIterable>::resolve(_iterator::owner.a, _iterator::it), _iterator::val); ++_iterator::it; return *this; }
	};
	inline iterator begin() const { return iterator(a.begin(), init_val, *this); }
	inline iterator end() const { return iterator(a.end(), _null<S>::value(), *this); }
	inline int size() const { return a.size(); }
	inline S resolve_iterator(const iterator &it) const
	{
		return f(citerator<InIterable>::resolve(a, it.it), it.val);
	}
    template<typename Ftr> inline
    void process(Ftr ftr) const
    {
        S cur = init_val;
        xforeach(a, x,
            cur = f(x, cur);
            if (!ftr(cur)) xbreak;
        )
    }
	ITER_WRITE
};
template<typename T, typename S, typename F> inline
FoldWrapper<T, S, F> create_fold_wrapper(const T &a, const S &init_val, F f)
{
    return FoldWrapper<T, S, F>(a, init_val, f);
}
#define _fold(name, a0, ftr, seq) \
	create_fold_wrapper(seq, a0, [&](const gcc_typename ValueType<decltype(seq)>::type &_, const decltype(a0) &name) { return ftr; })
template<typename T1, typename T2>
struct _pair
{
    tup2(type, T1, f, T2, s);
};
template<typename T1, typename T2>
typename _pair<T1, T2>::type PAIR(const T1 &f, const T2 &s)
{
	return typename _pair<T1, T2>::type(f, s);
}
template<typename T, typename F, typename S>
struct MapWrapper
{
	SEQ_TYPE(T) a;
	typedef S value_type;
	F f;
	MapWrapper(const T &a, F f) : a(a), f(f) {}
	typedef typename T::iterator iterator;
	inline iterator begin() const { return a.begin(); }
	inline iterator end() const { return a.end(); }
	inline int size() const { return a.size(); }
	inline S resolve_iterator(const iterator &it) const
	{
		return f(citerator<T>::resolve(a, it));
	}
    template<typename Ftr>
    inline void process(Ftr ftr) const
    {
        xforeach(a, x,
            if (!ftr(f(x))) xbreak
        );
    }
	ITER_WRITE
};
template<typename T, typename F>
auto SimpleMapWrapper(const T &a, F f) -> MapWrapper<T, F, decltype(f( gcc_typename ValueType<T>::type() ))>
{
	return MapWrapper<T, F, decltype(f( gcc_typename ValueType<T>::type() ))>(a, f);
}
#define _map(a, ...) SimpleMapWrapper(a, [&](const ValueType<decltype(a)>::type &_) \
	 { return __VA_ARGS__; })
template<
	typename T,
	typename Filter
>
struct FilterWrapper
{
	SEQ_TYPE(T) a;
	Filter filter;
	FilterWrapper(const T &a, Filter filter) : a(a), filter(filter) {}
	typedef typename T::value_type value_type;
	typedef _DummyType iterator;
	template<typename F>
	inline void process(F f) const
	{
		xforeach(a, x,
			if (filter(x))
				if (!f(x)) xbreak
		)
	}
    inline int size() const { return _count(*this); }
	ITER_WRITE
};
template<typename T, typename Filter>
inline FilterWrapper<T, Filter> CreateFilterWrapper(const T &t, Filter f)
{
	return FilterWrapper<T, Filter>(t, f);
}
#define _filter(cond, a) \
	CreateFilterWrapper(a, [&](const ValueType<decltype(a)>::type &_) -> bool { return cond; })
template<
    typename T
>
struct TakeWrapper
{
    SEQ_TYPE(T) a;
    int cnt;
    TakeWrapper(int cnt, const T &a) : cnt(cnt), a(a) { assert(cnt >= 0); }
    typedef typename T::value_type value_type;
    template<typename F>
    inline void process(F f) const
    {
		if (cnt <= 0) return;
        int i = 0;
        xforeach(a, x,
            if (!f(x)) xbreak;
			++i;
			if (i >= cnt) xbreak;
        )
    }
    inline int size() const { return min(cnt, (int)a.size()); }
    typedef _DummyType iterator;
	ITER_WRITE
};
template<typename T>
inline TakeWrapper<T> _take(int cnt, const T &a)
{
    return TakeWrapper<T>(cnt, a);
}
template<
	typename ListType,
	typename SeqType
>
void populate(ListType &lst, const SeqType &seq)
{
	xforeach(seq, x, lst.push_back(x));
}
template<typename T1, typename T2>
struct ConcatLists
{
    typedef typename T1::value_type value_type;
    SEQ_TYPE(T1) a;
    SEQ_TYPE(T2) b;
    ConcatLists(const T1 &a, const T2 &b) : a(a), b(b) {}
    template<typename F>
    inline void process(F f) const
    {
		bool stop = false;
		xforeach(a, i, if (!f(i)) { stop = true; xbreak; } )
        if (!stop) xforeach(b, i, if (!f(i)) xbreak )
    }
    inline int size() const { return a.size() + b.size(); }
	typedef _DummyType iterator;
	ITER_WRITE
};
template<typename T>
struct __lcat
{
	const T &a;
	__lcat(const T &a) : a(a) {}
	template<typename T2> inline
		ConcatLists<T, T2> operator % (const T2 &b) const { return ConcatLists<T, T2>(a, b); }
};
struct _lcat {};
template<typename T> inline
	__lcat<T> operator % (const T &a, _lcat) { return __lcat<T>(a); }
#define lcat _lcat() %
template<typename T>
inline int _count(const T &a)
{
    int res = 0;
    xforeach(a, i, ++res);
    return res;
}
template<
	typename T,
	typename S,
	typename StopFtr,
	typename GenFtr,
	typename TransformFtr
>
struct GenWrapper
{
	T a0;
	StopFtr stop_ftr;
	GenFtr gen_ftr;
	TransformFtr transform_ftr;
	typedef S value_type;
	GenWrapper(const T &a0, StopFtr stop_ftr, GenFtr gen_ftr, TransformFtr transform_ftr)
		: a0(a0), stop_ftr(stop_ftr), gen_ftr(gen_ftr), transform_ftr(transform_ftr) {}
	template<typename F>
	inline void process(F f) const
	{
		T cur = a0;
		while (stop_ftr(cur))
		{
			if (!f(gen_ftr(cur))) return;
			cur = transform_ftr(cur);
		}
	}
	inline int size() const { return _count(*this); }
    typedef _DummyType iterator;
	ITER_WRITE
};
template<
	typename T,
	typename StopFtr,
	typename GenFtr,
	typename TransformFtr
>
inline auto create_gen(const T &a0, StopFtr stop_ftr, GenFtr gen_ftr, TransformFtr transform_ftr) ->
GenWrapper<T, decltype(gen_ftr(T())), StopFtr, GenFtr, TransformFtr>
{
	return GenWrapper<T, decltype(gen_ftr(T())), StopFtr, GenFtr, TransformFtr>(a0, stop_ftr, gen_ftr, transform_ftr);
}
#define _gen(name, a0, stop_ftr, gen_ftr, transform_ftr) \
	create_gen(a0, [&](const decltype(a0) &name) -> bool { return stop_ftr; }, \
				   [&](const decltype(a0) &name) { return gen_ftr; }, \
				   [&](const decltype(a0) &name) -> decltype(a0) { return transform_ftr; })
template<typename T, typename F>
inline typename T::value_type _Collapse(const T &a, F f)
{
	typedef typename T::value_type S;
	S res;
	bool first = true;
	xfor(a, x,
		if (first)
		{
			res = x;
			first = false;
		}
		else
		{
			res = f(x, res);
		}
	);
	return res;
}
#define _collapse(name, ftr, seq) \
	_Collapse(seq, [&](const gcc_typename ValueType<decltype(seq)>::type &_, const gcc_typename ValueType<decltype(seq)>::type &name) { return ftr; })
#ifndef ONLINE_JUDGE
#define _open_files(name) freopen(name ".in", "r", stdin); freopen(name ".out", "w", stdout)
#else
#define _open_files(name)
#endif
#define _END_SOL int main() { _open_files("test"); solve(); return 0; }
_SOLUTION


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

int main() {
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);
	cerr.sync_with_stdio(false);

	int N, V; cin >> N >> V;

	vector<pair<int,int>> wv[2];
	wv[0].reserve(N);
	wv[1].reserve(N);

	for (int i = 1; i < N+1; i++) {
		int a, b; cin >> a >> b;
		wv[a-1].emplace_back(b, i);
	}

	for (int a = 0; a < 2; a++) {
		sort(wv[a].begin(), wv[a].end(), greater<pair<int,int>>());
		int tmp = 0;
		for (int i = 0; i < int(wv[a].size()); i++) {
			tmp += wv[a][i].first;
			wv[a][i].first = tmp;
		}
	}

	int bestP = 0, best[2] = {-1, -1};
	for (int i = 0; i < int(wv[0].size())+1; i++) {
		if (i > V) break;

		int j = (V - i) / 2;
		j = min(j, int(wv[1].size()));

		int P = 0;
		if (i > 0) P += wv[0][i-1].first;
		if (j > 0) P += wv[1][j-1].first;

		if (P > bestP) {
			bestP = P;
			best[0] = i;
			best[1] = j;
		}
	}
	cout << bestP << endl;
	bool first = true;
	for (int a = 0; a < 2; a++) {
		for (int i = 0; i < best[a]; i++) {
			if (first) first = false;
			else       cout << " ";
			cout << wv[a][i].second;
		}
	}
	cout << endl;
}


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

int main() {
	cin.sync_with_stdio(false);
	cout.sync_with_stdio(false);
	cerr.sync_with_stdio(false);

	int N, V; cin >> N >> V;

	vector<tuple<int,int,int>> wv;
	wv.reserve(N);

	for (int i = 1; i < N+1; i++) {
		int a, b; cin >> a >> b;
		wv.emplace_back(b * (3-a), a, i);
	}
	sort(wv.begin(), wv.end(), greater<tuple<int,int,int>>());

	vector<int> result;
	result.reserve(N);
	int P = 0;
	for (const auto& e : wv) {
		if (V <= 0) {
			assert(V == 0);
			break;
		}
		if (V == 1 && get<1>(e) != 1)
			continue;

		P += get<0>(e) / (3 - get<1>(e));
		V -= get<1>(e);
		result.push_back(get<2>(e));
	}
	cout << P << endl;
	copy(result.begin(), result.end(), ostream_iterator<int>(cout, " "));
	cout << endl;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		int kayaks_sum = 0;
		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (ksize > 0 && v > 2 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();
			--ksize;

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();
			ksize -= 2;

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

inline bool is_greater(const std::pair<int, int> &lhs, const std::pair<int, int> &rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v & 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				kayaks.pop_front();
				--ksize;
				--v;
				answer += kayaks.cbegin()->second;
				continue;
			}
		}

		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;

		int kayaks_sum = 0;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (v == 3 && ksize > 1 && csize > 0) {
			int additional_v = 0;
			if (ksize > 2) {
				additional_v = std::next(kcit2)->second;
			}
			if (kcit1->second + catamarans_sum > kayaks_sum + additional_v) {
				targets.push_back(kcit1->first);
				targets.push_back(ccit->first);

				answer += kcit1->second;
				answer += ccit->second;
				break;
			}
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			kayaks.pop_front();
			--ksize;
			--v;

			if (ksize > 1) {
				targets.push_back(kcit2->first);
				kayaks.pop_front();
				--ksize;
				--v;
			}

			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1)
			kayaks.push_back(std::make_pair(i + 1, capacity));
		else
			catamarans.push_back(std::make_pair(i + 1, capacity));
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	while (v > 0) {
		if (v == 1) {
			targets.push_back(kayaks.cbegin()->first);
			answer += kayaks.cbegin()->second;
			break;
		}

		int kayaks_sum = 0;
		auto kcit1 = kayaks.cbegin();
		kayaks_sum += kcit1->second;
		auto kcit2 = std::next(kcit1);
		kayaks_sum += kcit2->second;

		auto ccit = catamarans.cbegin();
		int catamarans_sum = ccit->second;

		if (kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();

			v -= 2;
			answer += kayaks_sum;
		} else {
			targets.push_back(ccit->first);

			catamarans.pop_front();

			v -= 2;
			answer += catamarans_sum;
		}
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;

		int kayaks_sum = 0;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (v == 3 && ksize > 1 && csize > 0) {
			int additional_v = 0;
			if (ksize > 2) {
				additional_v = std::next(kcit2)->second;
			}
			if (kcit1->second + catamarans_sum > kayaks_sum + additional_v) {
				targets.push_back(kcit1->first);
				targets.push_back(ccit->first);

				answer += kcit1->second;
				answer += ccit->second;
				break;
			}
		}

		if (ksize > 0 && v > 2 && kcit1->second >= catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();
			--ksize;

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();
			ksize -= 2;

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		int kayaks_sum = 0;
		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (ksize > 0 && v > 2 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();
			--ksize;

			--v;
			answer += kcit1->second;

			continue;
		}

		if (v == 3 && ksize > 1 && csize > 0) {
			if (kcit1->second + catamarans_sum > kayaks_sum) {
				targets.push_back(kcit1->first);
				targets.push_back(ccit->first);

				answer += kcit1->second;
				answer += ccit->second;
				break;
			}
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();
			ksize -= 2;

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

inline bool is_greater(const std::pair<int, int> &lhs, const std::pair<int, int> &rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v & 1) {
			if (ksize > 0) {
				answer += kayaks.cbegin()->second;
				targets.push_back(kayaks.cbegin()->first);
				kayaks.pop_front();
				--ksize;
				--v;
				continue;
			}
		}

		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;

		int kayaks_sum = 0;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			kayaks.pop_front();
			--ksize;
			--v;

			if (ksize > 0) {
				targets.push_back(kcit2->first);
				kayaks.pop_front();
				--ksize;
				--v;
			}

			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize, csize;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		int kayaks_sum = 0;
		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (ksize > 0 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
#include <list>

bool is_greater(const std::pair<int, int> lhs, const std::pair<int, int> rhs)
{
	return lhs.second > rhs.second;
}

int main()
{
	int n, v, type, capacity;
	std::list<std::pair<int, int>> kayaks;
	std::list<std::pair<int, int>> catamarans;
	int ksize = 0, csize = 0;

	scanf("%d %d", &n, &v);
	for (int i = 0; i < n; ++i) {
		scanf("%d %d", &type, &capacity);

		if (type == 1) {
			kayaks.push_back(std::make_pair(i + 1, capacity));
			++ksize;
		} else {
			catamarans.push_back(std::make_pair(i + 1, capacity));
			++csize;
		}
	}

	kayaks.sort(is_greater);
	catamarans.sort(is_greater);

	std::vector<int> targets;
	long long answer = 0;

	auto canAdd = [&] () {
		if (v <= 0) return false;
		if (ksize > 0) return true;
		if (v > 1 && (csize > 0)) return true;
		return false;
	};

	while (canAdd()) {
		if (v == 1) {
			if (ksize > 0) {
				targets.push_back(kayaks.cbegin()->first);
				answer += kayaks.cbegin()->second;
			}
			break;
		}

		int kayaks_sum = 0;
		std::list<std::pair<int, int>>::const_iterator kcit1, kcit2, ccit;
		if (ksize > 0) {
			kcit1 = kayaks.cbegin();
			kayaks_sum += kcit1->second;
			if (ksize > 1) {
				kcit2 = std::next(kcit1);
				kayaks_sum += kcit2->second;
			}
		}

		int catamarans_sum = 0;
		if (csize > 0) {
			ccit = catamarans.cbegin();
			catamarans_sum = ccit->second;
		}

		if (ksize > 0 && kcit1->second > catamarans_sum) {
			targets.push_back(kcit1->first);

			kayaks.pop_front();
			--ksize;

			--v;
			answer += kcit1->second;

			continue;
		}

		if (kayaks_sum > catamarans_sum) {
			targets.push_back(kcit1->first);
			targets.push_back(kcit2->first);

			kayaks.pop_front();
			kayaks.pop_front();
			ksize -= 2;

			v -= 2;
			answer += kayaks_sum;
		} else if (catamarans_sum > 0) {
			targets.push_back(ccit->first);

			catamarans.pop_front();
			--csize;

			v -= 2;
			answer += catamarans_sum;
		} else break;
	}

	std::cout << answer << std::endl;
	for (auto cit = targets.cbegin(); cit != targets.cend(); ++cit)
		printf("%d ", *cit);

	return 0;
}