//
紫书刘汝佳源代码, 运用了回溯寻找最优决策
话说是不是回溯都要递推, 做题太少, 嗯直觉是动归加回溯肯定是要逆推
//
#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#define INF 100000000;
using namespace std;
const int maxn = 100 + 5;
int a[maxn][maxn];
int d[maxn][maxn];
int next_[maxn][maxn];
int main()
{
int m , n;
while(cin >> m >> n)
{
for(int i = 0; i < m; ++i)
for(int j = 0; j < n; ++j)
scanf("%d", &a[i][j]);
int ans = INF;
int first = 0;
for(int j = n -1; j >= 0; --j) // 逆推
{
for(int i = 0; i < m; ++i)
{
if(j==n-1) d[i][j] = a[i][j]; // 边界
else
{
int rows[3] = {i, i-1, i+1};
if(i==0) rows[1] = m - 1; //第0行上面是第m-1行
if(i==m-1) rows[2] = 0;//第m-1行下面是第0行
sort(rows, rows+3); //重新排序, 以便找到字典序最小的
d[i][j] = INF;
for(int k = 0; k < 3; ++k)
{
int v = d[rows[k]][j+1] + a[i][j];
if(v<d[i][j])
{
d[i][j] = v;
next_[i][j] = rows[k];
}
}
}
if(j==0 && d[i][j] < ans)
{
ans = d[i][j];
first = i;
}
}
}
printf("%d", first + 1); // 输出第一列
for(int i = next_[first][0], j = 1; j < n; i = next_[i][j], ++j)
printf(" %d",i+1);
printf("\n%d\n", ans);
}
return 0;
}