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

#define INF (1<<29)
#define MAX 55

typedef pair<int, int> P;

int N, D;
int cost[MAX][MAX];
P dp[MAX][MAX]; // dp[何泊目][泊まってるホテル] := (宿泊代の合計, 移動回数)

bool isValid(int p, int m, vector<int> path){
  int sum = 0;
  int move = 0;
  for(int i = 0 ; i < (int)path.size() ; i++) sum += cost[i][path[i]];
  for(int i = 1 ; i < (int)path.size() ; i++){
    if(path[i] != path[i-1]) move++;
  }
  if(p == sum && move == m) return true;
  else return false;
}

int main(){
  cin >> N >> D;
  for(int i = 0 ; i < N ; i++)
    for(int j = 0 ; j < D ; j++) cin >> cost[j][i];
  
  for(int i = 0 ; i < MAX ; i++)
    for(int j = 0 ; j < MAX ; j++) dp[i][j].first = dp[i][j].second = INF;
  
  vector<int>  paths[MAX][MAX];
  for(int j = 0 ; j < N ; j++){
    dp[0][j] = P(cost[0][j], 0);
    vector<int> p;
    paths[0][j].push_back(j);
  }
  
  for(int i = 1 ; i < D ; i++){
    for(int k = 0 ; k < N ; k++){
      for(int j = 0 ; j < N ; j++){
	
	P next = dp[i-1][k];	  
	next.first += cost[i][j];
	if(j != k) next.second += 1;	  
	
	vector<int> path;
	path = paths[i-1][k];
	path.push_back(j);
	
	if(dp[i][j] >= next){
	  dp[i][j] = min(dp[i][j], next);
	  paths[i][j] = path;
	}
      }
    }
  }

 for(int i = 1 ; i < D ; i++){
    for(int k = N-1 ; k >= 0 ; k--){
      for(int j = N-1 ; j >= 0 ; j--){
	
	P next = dp[i-1][k];	  
	next.first += cost[i][j];
	if(j != k) next.second += 1;	  
	
	vector<int> path;
	path = paths[i-1][k];
	path.push_back(j);
	
	if(dp[i][j] >= next){
	  dp[i][j] = min(dp[i][j], next);
	  paths[i][j] = min(paths[i][j], path);
	}
      }
    }
  }

 for(int i = 1 ; i < D ; i++){
    for(int k = 0 ; k < N ; k++){
      for(int j = 0 ; j < N ; j++){
	
	P next = dp[i-1][k];	  
	next.first += cost[i][j];
	if(j != k) next.second += 1;	  
	
	vector<int> path;
	path = paths[i-1][k];
	path.push_back(j);
	
	if(dp[i][j] >= next){
	  dp[i][j] = min(dp[i][j], next);
	  paths[i][j] = min(paths[i][j], path);
	}
      }
    }
  }

  
  /*
  for(int i = 0 ; i < D ; i++){
    for(int j = 0 ; j < N ; j++){
      cout << " (" << dp[i][j].first << ", " << dp[i][j].second << ") "; 
    }
    cout << endl;
  }
*/
  P ans;
  ans.first = ans.second = INF;
  for(int j = 0 ; j < N ; j++) ans = min(ans, dp[D-1][j]);
  
  cout << ans.first << ' ' << ans.second << endl;
    
  vector<int> ans_path;
  
  for(int j = 0 ; j < N ; j++){
    if(dp[D-1][j] == ans){
      if(!isValid(ans.first, ans.second, paths[D-1][j])) continue;	
      if(ans_path.size() == 0) ans_path = paths[D-1][j];
      else ans_path = min(ans_path, paths[D-1][j]);
    }
  }
  
  if(ans_path.size() == 0) assert(false);
  for(int i = 0 ; i < ans_path.size() ; i++){
    cout << ans_path[i]+1 << endl;
  }
  return 0;
}