/*
本题感觉设计很巧妙,虽然很水,但是对于dfs不熟的我感觉还是很难。通过这道题,让我又对dfs多了一份了解。
首先本题是选出一些行是每一列只含有一个1.行最多也就16,枚举也就2^16,不算太大。还不到1000000,于是很适合
用dfs。中间的used的数组很精妙,used数组就是最终的结果。通过判断used是不是全是1来判断结果。通过每一行和used比较来
确定是否可以和used并,也就是说选这一行。然后就是dfs枚举所有的情况。首先是从0开始,如果一行满足就到下一行,否则就
回溯,一直到把所有情况都枚举完毕。本题600+MS感觉效率很低。不知道所谓的十字链表是不是效率高一点。
*/
#include<iostream>
using namespace std;
int num[20][310],m,n;
bool used[310];
bool find;
bool match()
{
int i;
for(i=0;i<n;i++)
{
if(!used[i])
return false;
}
return true;
}
bool check(int row)
{
int i;
for(i=0;i<n;i++)
{
if(used[i]&&num[row][i])
return false;
}
for(i=0;i<n;i++)
{
if(num[row][i])
used[i]=true;
}
return true;
}
void dfs(int s)
{
int i,j;
if(s>m||find)
return;
if(match())
{
printf("Yes, I found it/n");
find=true;
return;
}
for(i=s;i<m&&!find;i++)
{
if(check(i))
{
dfs(i+1);
for(j=0;j<n;j++)
{
if(num[i][j])
used[j]=false;
}
}
}
}
int main()
{
int i,j;
while(scanf("%d%d",&m,&n)!=EOF)
{
for(i=0;i<m;i++)
for(j=0;j<n;j++)
scanf("%d",&num[i][j]);
memset(used,0,sizeof(used));
find=false;
dfs(0);
if(!find)
printf("It is impossible/n");
}
return 0;
}