#include <stdio.h>
#include <cmath>
#include <math.h>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	bool operator<(const struct Info &arg)const{
		return sum_move > arg.sum_move;
	}
	int day,current_hotel,sum_move;
	int history[51];
};

struct Data{
	int move_num;
	int min_history[51];
};

Data min_data[51][51];

bool isSame(int day,int table1[51],int table2[51]){

	for(int i = 1; i <= day; i++){
		if(table1[i] != table2[i]){
			return false;
		}
	}

	return true;
}

int main(){

	int N,D;
	scanf("%d %d",&N,&D);

	int min_cost[D+1];
	for(int day = 1; day <= D; day++)min_cost[day] = BIG_NUM;

	int cost[N+1][D+1];
	for(int hotel = 1; hotel <= N; hotel++){
		for(int day = 1; day <= D; day++){
			scanf("%d",&cost[hotel][day]);
			min_cost[day] = min(min_cost[day],cost[hotel][day]);
		}
	}

	vector<int> MIN_COST_HOTEL[D+1];

	for(int day = 1; day <= D; day++){
		for(int hotel = 1; hotel <= N; hotel++){
			if(cost[hotel][day] == min_cost[day])MIN_COST_HOTEL[day].push_back(hotel);
		}
	}

	for(int day = 1; day <= D; day++){
		for(int hotel = 1; hotel <= N; hotel++){
			min_data[day][hotel].move_num = BIG_NUM;
		}
	}

	priority_queue<Info> Q;
	for(int i = 0; i < MIN_COST_HOTEL[1].size(); i++){
		Info new_info;
		new_info.day = 1;
		new_info.current_hotel = MIN_COST_HOTEL[1][i];
		new_info.sum_move = 0;
		new_info.history[1] = MIN_COST_HOTEL[1][i];
		min_data[1][MIN_COST_HOTEL[1][i]].move_num = 0;
		min_data[1][MIN_COST_HOTEL[1][i]].min_history[1] = MIN_COST_HOTEL[1][i];
		Q.push(new_info);
	}

	int ans[51],minimum_move = BIG_NUM;
	int ans_index,tmp_index,next_hotel,next_move;

	bool FLG;

	while(!Q.empty()){

		FLG = true;
		for(int day = 1; day <= Q.top().day; day++){
			if(Q.top().history[day] != min_data[Q.top().day][Q.top().current_hotel].min_history[day]){
				FLG = false;
				break;
			}
		}

		if(!FLG){
			Q.pop();
			continue;
		}

		if(Q.top().day == D){

			if(minimum_move > Q.top().sum_move){
				minimum_move = Q.top().sum_move;
				for(int day = 1; day <= D; day++){
					ans[day] = Q.top().history[day];
				}
			}else if(minimum_move == Q.top().sum_move){

				ans_index = tmp_index = 1;
				while(ans[ans_index] == Q.top().history[tmp_index]){
					ans_index++;
					tmp_index++;
				}
				if(ans[ans_index] > Q.top().history[tmp_index]){
					for(int day = 1; day <= D; day++){
						ans[day] = Q.top().history[day];
					}
				}
			}
			Q.pop();
		}else if(Q.top().sum_move > min_data[Q.top().day][Q.top().current_hotel].move_num){
			Q.pop();
		}else{

			for(int i = 0; i < MIN_COST_HOTEL[Q.top().day+1].size(); i++){
				next_hotel = MIN_COST_HOTEL[Q.top().day+1][i];

				if(next_hotel == Q.top().current_hotel){
					next_move = Q.top().sum_move;
				}else{
					next_move = Q.top().sum_move+1;
				}

				if(min_data[Q.top().day+1][next_hotel].move_num > next_move){
					min_data[Q.top().day+1][next_hotel].move_num = next_move;
					for(int k = 1; k <= Q.top().day; k++)min_data[Q.top().day+1][next_hotel].min_history[k] = Q.top().history[k];
					min_data[Q.top().day+1][next_hotel].min_history[Q.top().day+1] = next_hotel;

					Info new_info;
					new_info.day = Q.top().day+1;
					new_info.current_hotel = next_hotel;
					new_info.sum_move = next_move;
					for(int k = 1; k <= Q.top().day; k++)new_info.history[k] = Q.top().history[k];
					new_info.history[Q.top().day+1] = next_hotel;
					Q.push(new_info);
				}else if(min_data[Q.top().day+1][next_hotel].move_num == next_move){
					ans_index = tmp_index = 1;
					while(min_data[Q.top().day+1][next_hotel].min_history[ans_index] == Q.top().history[tmp_index]){
						ans_index++;
						tmp_index++;
					}
					if(min_data[Q.top().day+1][next_hotel].min_history[ans_index] > Q.top().history[tmp_index]){

						for(int day = 1; day <= D; day++){
							min_data[Q.top().day+1][next_hotel].min_history[day] = Q.top().history[day];
						}
						min_data[Q.top().day+1][next_hotel].min_history[Q.top().day+1] = next_hotel;

						Info new_info;
						new_info.day = Q.top().day+1;
						new_info.current_hotel = next_hotel;
						new_info.sum_move = next_move;
						for(int k = 1; k <= Q.top().day; k++)new_info.history[k] = Q.top().history[k];
						new_info.history[Q.top().day+1] = next_hotel;
						Q.push(new_info);
					}
				}
			}
			Q.pop();
		}
	}

	int P = 0;
	for(int day = 1; day <= D; day++)P += min_cost[day];

	printf("%d %d\n",P,minimum_move);
	for(int day = 1; day <= D; day++)printf("%d\n",ans[day]);

	return 0;
}

Measured memory_bytes: 6892