#include <bits/stdc++.h>
using namespace std;
template <typename T>
using v = vector<T>;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using vi = vector<int>;
using vll = vector<ll>;
using ui = unsigned int;
using vpii = vector<pii>;
using vvi = vector<vi>;
#define pb push_back
#define all(_) _.begin(), _.end()
constexpr int MXN = 200003;
constexpr ll INF = 200000000000000;
constexpr int MOD = 1;
constexpr int LOG = bit_width(ui(MXN));
int n, k;
struct c{
int t, p, id;
c(int a, int b, int c_){
t = a;
p = b;
id = c_;
}
};
vi answ;
vpii T1;
v<c> M1, M;
__int128 X;
ll dp[MXN][67];
bool comp(c x, c y){
return (ll)x.p*x.t*y.t - (ll)y.t*y.p < (ll)y.p*y.t*x.t - (ll)x.t*x.p;
}
bool win_win(){
k=0;
while(k<n){
auto [t,p,id] = M1[k];
__int128 next = (X-p)*t;
if(next >= INF){
answ.clear();
for(auto &[t,p,id] : M1) answ.pb(id);
for(auto &[p, id]: T1) answ.pb(id);
return true;
}
if(next >= X){
answ.pb(id);
X = next;
k++;
}
else break;
}
return false;
}
void retrieve(int comprado){
vi v;
while(n && comprado){
ll prev = dp[n-1][comprado-1];
ll actual = dp[n][comprado];
auto [t, p, id] = M[n-1];
if(actual == (prev-p)*t){
v.pb(id);
comprado--;
}
n--;
}
reverse(all(v));
answ.insert(answ.begin(), all(v));
}
vi max_coupons(int A, vi P, vi T){
X = A;
n = T.size();
for(int i=0; i<n; i++){
if(T[i] == 1) T1.pb({P[i], i});
else{
M1.pb(c(T[i],P[i],i));
}
}
vll pref(T1.size());
bool hayT1 = 0;
if(T1.size()){
hayT1 = 1;
pref[0] = T1[0].first;
for(int i=1; i<T1.size(); i++) pref[i] = pref[i-1] + T1[i].first;
}
sort(all(T1));
sort(all(M1), comp);
n = M1.size();
if(win_win()) return answ;
M.insert(M.end(), M1.begin()+k, M1.end());
for(int i=0; i<MXN; i++){
for(int j=0; j<67; j++) dp[i][j] = -1;
}
n = M.size();
for(int i=0; i<=n; i++){
dp[i][0] = X;
}
dp[0][0] = X; // puede ser que faltaba esto para i=j=1.
for(int i=1; i<=n; i++){
int tope = min(66, i);
auto [t, p, id] = M[i-1];
for(int j=1; j<=tope; j++){
ll prev = dp[i-1][j-1];
ll neww = prev >= p ? (prev-p)*t : -1;
dp[i][j] = max(dp[i-1][j], neww);
}
}
int MX_T1 = 0;
int MX_other = 0;
for(int i=0; i<67; i++){
ll sobra = dp[n][i];
if(sobra < 0) continue;
ll extra = hayT1 ? upper_bound(all(pref), sobra) - pref.begin() : 0;
if(i + extra > MX_T1 + MX_other){
MX_T1 = extra;
MX_other = i;
}
}
retrieve(MX_other);
for(int i=0; i<MX_T1; i++) answ.pb(T1[i].second);
return answ;
}