// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

#define rep(i,n) for(int (i)=0; (i)<(int)(n); (i)++)

#define all(x) (x).begin(),(x).end()



const int N = 55;

const int INF = 19191919;

int n,d;

int p[N][N];



int dp[N][N][N];

int par[N][N][N];

int ok[N][N][N] = {};



int main(){

  cin >>n >>d;

  rep(i,n)rep(j,d) cin >>p[i][j];

  

  rep(i,N)rep(j,N)rep(k,N)

  {

    dp[i][j][k] = INF;

    par[i][j][k] = INF;

  }

  

  rep(i,n) dp[0][0][i] = 0;

  

  rep(i,d)rep(j,N-1)rep(k,n)

  {

    // next stay

    rep(l,n)

    {

      int nj = j+(k!=l);

      if(dp[i+1][nj][l] > dp[i][j][k]+p[l][i])

      {

        dp[i+1][nj][l] = dp[i][j][k]+p[l][i];

        par[i+1][nj][l] = k;

      }

      else if(dp[i+1][nj][l] == dp[i][j][k]+p[l][i])

      {

        par[i+1][nj][l] = min(par[i+1][nj][l], k);

      }

    }

  }

  

  int P = INF;

  int M = INF;

  rep(i,N)rep(j,n) P = min(P,dp[d][i][j]);

  rep(i,N)rep(j,n)if(dp[d][i][j] == P) M = min(M, i);

  rep(i,n)if(dp[d][M][i] == P) ok[d][M][i] = 1;

  

  for(int i=d; i>=1; --i)rep(j,N)rep(k,n)

  {

    if(!ok[i][j][k]) continue;

    

    // stayed before

    rep(l,n)

    {

      int bj = j - (k!=l);

      if(bj<0) continue;

      

      if(dp[i][j][k] - p[k][i-1] == dp[i-1][bj][l]) ok[i-1][bj][l] = 1;

    }

  }

  

  

  vector<int> ans(d,INF);

  rep(i,n)

  {

    if(!ok[0][0][i]) continue;

     

    vector<int> t(d);

    int now = i;

    int ct = 0;

    

    rep(j,d)

    {

      rep(k,n)

      {

        int nct = ct + (now!=k);

        if(ok[j+1][nct][k])

        {

          t[j] = k;

          ct = nct;

          now = k;

          break;

        }

      }

    }

    

    /*

    printf(" GO %d\n", i);    

    rep(j,d) cout << t[j]+1 << endl;

    */

    ans = min(ans,t);

  }



  cout << P << " " << M << endl;

  rep(i,d) cout << ans[i]+1 << endl;

  return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

#define GET_MACRO(_1, _2, _3, NAME, ...) NAME

#define _repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)

#define _rep(i,n) _repl(i,0,n)

#define rep(...) GET_MACRO(__VA_ARGS__, _repl, _rep)(__VA_ARGS__)

#define mp(a,b) make_pair((a),(b))

#define pb(a) push_back((a))

#define all(x) (x).begin(),(x).end()

#define uniq(x) sort(all(x)),(x).erase(unique(all(x)),end(x))

#define fi first

#define se second

#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)

void _dbg(string){cout<<endl;}

template<class H,class... T> void _dbg(string s,H h,T... t){int l=s.find(',');cout<<s.substr(0,l)<<" = "<<h<<", ";_dbg(s.substr(l+1),t...);}

template<class T,class U> ostream& operator<<(ostream &o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}

template<class T> ostream& operator<<(ostream &o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}



#define INF 1120000000

#define long long long // for codeforces



int dp[55][55];

int pr[55][55];



int main(){

  int n,d;

  cin>>n>>d;

  vector<vector<int>> p(n,vector<int>(d));

  rep(i,n) rep(j,d) cin>>p[i][j];



  fill(dp[0], dp[d+1], INF);

  rep(i,n) dp[d][i] = 0;



// ???????????????????????????????????¨?????????



  int tot = 0;

  for(int i = d; i>0; i--){

    int mn = INF;

    rep(j,n) mn = min(mn, p[j][i-1]);

    tot += mn;

    rep(j,n) if(dp[i][j]<INF){

      rep(k,n) if(p[k][i-1] == mn){

        int nv = dp[i][j] + (j!=k);

        if(dp[i-1][k] > nv){

          dp[i-1][k] = nv;

          pr[i-1][k] = j;

        }

      }

    }

  }



  int av = INF, ai = -1;

  rep(i,n) if(dp[0][i] < av){ av = dp[0][i]; ai = i; }



  vector<int> ans;

  rep(i,d){

    ans.pb(ai+1);

    ai = pr[i][ai];

  }



  cout << tot << " " << av << "\n";

  rep(i,d) cout << ans[i] << "\n";





  return 0;

}

// Fastest known solution for this problem: