#include<bits/stdc++.h>
using namespace std;
int n,dp[100001],v[100001],c[100001],l[100001],r[100001],maxx=0,ok[100001],ll,num=0,m=0;
vector<int> hash[100000];
//方法:使用一维数组,dp[a]表示有a且以a为结尾的最大值,那么a的前后数目都确定了,
//对于1<=k<a,判断l[k]+c[k]和l[a],来决定可不可以有k,同样r[k]!=c[a]+r[a];
//初始值:对于l[a]==0的都可以作为第一个,则return v[a]
//可以改用循环更快
int DP(int a){
if(l[a]==0) return v[a];
if(dp[a]!=0) return dp[a];
for(vector<int>::iterator i=hash[l[a]].begin();i!=hash[l[a]].end();i++){
if(*i>=a||r[*i]!=c[a]+r[a]) continue;//因为用了hash,可能*i>=a,本来会循环到a-1的,不会出现这种情况
if(DP(*i)+v[a]>dp[a]){
dp[a]=DP(*i)+v[a];
ok[a]=*i;//前驱数组
}
}
if(dp[a]>maxx&&r[a]==0){//r[a]==0才更新最优解,平常不限制最后一个r[a]==0,否则无法循环。都是0;
maxx=dp[a];
ll=a;//最优值的位置
}
return dp[a];
}
void show(int k){
if(k==-1) return;
m+=v[k];
show(ok[k]);
cout<<k<<" ";
}
int main() {
cin>>n;
memset(dp,0,sizeof(dp));
memset(ok,255,sizeof(ok));
for(int i=1;i<=n;i++){
cin>>v[i]>>c[i]>>l[i]>>r[i];
hash[c[i]+l[i]].push_back(i);
}
for(int i=1;i<=n;i++) DP(i);
//保证得到最优解,其实只需循环r[i]==0的点就行了,
//但是事实上,后面的都会用到前面的,因为我是递归,所以直接递归后面反而会变慢
int p=ll;
while(ll!=-1){
ll=ok[ll];
num++;
}
cout<<num<<endl;
show(p);
cout<<endl;
cout<<maxx<<endl;
return 0;
}