rt
#include<bits/stdc++.h>
using namespace std;
const int N=6e3+7;
int ans[N],siz[N],tot;
struct DLXnode
{
int row,col,left,right,up,down;
DLXnode(){}
DLXnode(int a0,int a1,int a2,int a3,int a4,int a5)
{
row=a0,col=a1,left=a2,right=a3,up=a4,down=a5;
}
}p[N];
inline void remove(int c)
{
int i,j;
p[p[c].left].right=p[c].right;
p[p[c].right].left=p[c].left;
for(i=p[c].down;i!=c;i=p[i].down)
for(j=p[i].right;j!=i;j=p[j].right)
{
p[p[j].up].down=p[j].down;
p[p[j].down].up=p[j].up;
--siz[c];
}
}
inline void resume(int c)
{
int i,j;
p[p[c].left].right=c;
p[p[c].right].left=c;
for(i=p[c].down;i!=c;i=p[i].down)
for(j=p[i].right;j!=i;j=p[j].right)
{
p[p[j].up].down=j;
p[p[j].down].up=j;
++siz[c];
}
}
bool dance(int now)
{
int i,j,c;
if(p[0].right==0)
{
for(i=1;i<now;++i) cout<<ans[i]<<' ';
return 1;
}
c=p[0].right;//剪枝
for(i=p[0].right;i!=0;i=p[i].right)
if(siz[i]<siz[c]) c=i;
remove(c);
for(i=p[c].down;i!=c;i=p[i].down)
{
ans[now]=p[i].row;
for(j=p[i].right;j!=i;j=p[j].right) remove(p[j].col);
if(dance(now+1)) return 1;
for(j=p[i].right;j!=i;j=p[j].right) resume(p[j].col);
}
resume(c);
return 0;
}
int main()
{
ios::sync_with_stdio(0),cin.tie(0);
int n,m,i,j,last,x;
cin>>n>>m;
//init DLX
for(i=0;i<=m;++i) p[i]=DLXnode(0,i,i-1,i+1,i,i);
p[0].left=m,p[m].right=0;
//build
tot=m;
for(i=1;i<=n;++i)
{
last=-1;
for(j=1;j<=m;++j)if(cin>>x,x)
{
++tot,++siz[j];
if(last==-1)
{
p[tot]=DLXnode(i,j,tot,tot,j,p[j].down);
p[j].down=p[p[j].down].up=tot;
}
else
{
p[tot]=DLXnode(i,j,p[last].left,last,j,p[j].down);
p[j].down=p[p[j].down].up=tot;
p[last].left=p[p[last].left].right=tot;
}
last=tot;
}
}
//dance!
if(!dance(1)) cout<<"No Solution!\n";
return 0;
}