#include <iostream>
using namespace std;
int main()
{
int i,n,x=0;
cin>>n;
int **p=new int *[n];//动态申请二维数组
int **q=new int *[n];//动态申请二维数组
int *r=new int[n];//动态申请一维数组
for(i=0;i<n;i++){
p[i]=new int[n];
q[i]=new int[n];
}
for(i=0;i<n;i++){
for(int j=0;j<=i;j++)
{
cin>>p[i][j];
q[i][j]=p[i][j];//完全将p这个二维数组的每个数都复制给q
}
}
for(i=1;i<n;i++)//第一步:处理三角形的一条直角边和斜边
{
p[i][0]+=p[i-1][0];
p[i][i]+=p[i-1][i-1];
}
for(i=2;i<n;i++)//第二步:处理中间部分,从上一行推出下一行的数
{
for(int j=1;j<i;j++)
{
if(p[i-1][j-1]>p[i-1][j])
p[i][j]+=p[i-1][j-1];
else p[i][j]+=p[i-1][j];
}
}
int maxa=p[n-1][0];
for(i=1;i<n;i++)//从p[][]的最后一行找最大的和
{
if(p[n-1][i]>maxa){
maxa=p[n-1][i];
x=i;//记录最后一行最大和的位置
}
}
cout<<maxa<<endl;
r[n-1]=q[n-1][x];
for(i=n-1;i>=1;i--)
{
if(p[i-1][x]==p[i][x]-q[i][x])//p-q得到另一个加数
{
r[i-1]=q[i-1][x];//将加数存起来,即:存下路径
}
else {
r[i-1]=q[i-1][x-1];//将加数存起来,即:存下路径
x=x-1;//纵坐标发生变化
}
}
for(i=0;i<n;i++)
{
cout<<r[i]<<" ";
}
delete []r;
for(i=0;i<n;i++)
{
delete[] p[i];delete[] q[i];//删除之前动态申请的空间
}
delete[] p;delete[] q;
return 0;
}