/**/ /*
    4种模式,问选哪种模式,使得棋盘变为0而且开关个数最少

    watashi博客说可以贪心,枚举第一行、列(与pattern有关!!!)
    然后去判断是否无解、唯一解
    他也提供了一种高斯消元做,然后再二进制枚举的方法

    不确定自由变元个数是多少,他说:
    "根据另一种枚举加贪心的算法,枚举第一列只有2^15的情况,每次枚举,要么没解,要么只有一个解"
    
    神奇~~

    这里的高斯消元按照的方法:
    
http://hi.baidu.com/czyuan_acm/blog/item/ebf41f8fdc0e1ee6f01f36e9.html
    “枚举k从0到equ – 1,当前处理的列为col(初始为0) ,每次找第k行以下(包括第k行),col列中元素绝对值
    最大的列与第k行交换。    如果col列中的元素全为0,那么则处理col + 1列,k不变。”

    我按照上面方法写,而且看了watashi的高斯消元,发现还可以列交换的,然后就方便回代了!!

    注意为增广矩阵赋值时的小标范围控制,不要越界了!!
*/

#include
< cstdio >
#include
< cstring >
#include
< algorithm >
#include
< vector >

using   namespace  std;

const   int  MAXN  =   16 * 16 ;
const   int  INF  =   1000000000 ;

const   char   * light[]  =
{    
    
".*.**..**.**",
    
"***********.",
    
".*.**..**",
}
;

bool  T[ 16 ][ 16 ];
bool  A[MAXN][MAXN] , x[MAXN];

#define  getID(x,y) ((x)*m + (y))
#define  get(x,y) ((x)&(1<<(y)))

int  guass( bool  A[][MAXN] ,  int  n)
{
    
int row , col;
    
for(row = 0 , col = 0 ; col < n ; col++)//make sure  (< row , < col)   = 0
    {
        
int id = row;
        
for(;A[id][col] == false && id < n;id++);

        
if(id == n) continue;    //all A[i][col] = 0

        
if(id != row)
        
{
            
for(int j = col ; j <=n ; j++)
                swap(A[row][j] , A[id][j]);
        }


        
if(col != row)//列交换  为了使得最后的矩阵前面的对角线都为1,方便回代
        {           //但这样会影响最后的解x[],因为被交换过了,但这种题不需要求出x[]
            for(int i = 0 ; i < n ; i++)
                swap(A[i][row] , A[i][col]);
        }

                                                        
        
for(int i = row + 1; i < n; i++)
        
{
            
if(A[i][row] == false)continue;
            
for(int j = row; j <= n; j++)
                A[i][j] 
^= A[row][j];
        }

        row
++;
    }

    
return row;
}


int  cal( bool  A[][MAXN] ,  bool  x[] ,  int  n ,  int  num)
{
    
int all = 0;
    
for(int i = 0 ; i < num ; i++)
        all 
+= x[n-1-i];
    
for(int i = n-1-num ; i >= 0 ; i--)
    
{
        
int y = A[i][n];
        
for(int j = n-1; j > i ; j--)
            y 
^= (A[i][j]&x[j]);
        x[i] 
= y;
        all 
+= x[i];
    }

    
return all;
}


int  solve( bool  A[][MAXN] ,  int  n)
{
    
int row = guass(A,n);

    
for(int i = row ; i < n ; i++)
    
{
        
if(A[i][n])return INF;//no solution
    }
    
    
    
int num = n - row;
    
int limit = 1<<num , ans = INF;
    
for(int i = 0 ; i < limit ; i++)
    
{
        
for(int j = 0 ; j < n ; j++) x[j] = false;
        
for(int j = 0 ; j < num ; j++)
        
{
            
if(get(i,j))
            
{
                x[n
-1-j] = 1;
            }

        }

        ans 
= min(ans , cal(A,x,n,num));
    }

    
return ans;
}


int  main()
{
#ifdef ONLINE_JUDGE
#else 
    freopen(
"in","r",stdin);
    
//freopen("out","w",stdout);
#endif

    
int n , m;
    
while( scanf("%d%d",&n,&m) , n || m)
    
{
        
int nm = n*m;

        
char str[100];

        
for(int i = 0 ; i < n ; i++)
        
{
            scanf(
"%s",str);
            
for(int j = 0 ; j < m ;j++)
            
{
                T[i][j] 
= (str[j] == '1') ;
            }

        }

    
        
int ans = INF , pattern; 
        
for(int k = 0 ; k < 4; k++)
        
{
            memset(A,
0,sizeof(A));
            
//build A[][]
            for(int i = 0; i < n; i++)
                
for(int j = 0 ; j < m ; j++)
                
{
                    
for(int ii = 0; ii < 3; ii++)
                        
for(int jj = 0 ; jj < 3; jj++)
                        
{
                            
if(i-1+ii>=0 && j-1+jj>=0 && i-1+ii < n && j-1+jj < m)//注意范围控制!也得<n,m
                            {
                                A[getID(i
-1+ii , j-1+jj)][getID(i,j)] = (light[ii][3*k+jj] == '*');                                
                            }

                        }

                    A[getID(i,j)][nm] 
= T[i][j];
                }


    
/**//*    puts("A::::");
        for(int ii = 0 ; ii < nm ;ii++)
        {
            for(int jj = 0 ;jj<= nm;jj++)
                printf("%d ",A[ii][jj]);
            puts("");
        }
*/


            
int _ans = solve(A,nm);

            
//printf("%d %d\n",k+1,_ans);

            
if(_ans < ans)
            
{
                ans 
= _ans;
                pattern 
= k+1;
            }

        }


        
if(ans >= INF)puts("Impossible");
        
else printf("%d %d\n",pattern,ans);
    }

    
return 0;
}