program writing;
var
f:array[0..10,1..9,0..2000000]of byte;
fu:array[0..10,1..9,0..2000000]of boolean;
t:array[0..10,0..10]of longint;
maxopt,n,m:longint;
procedure init;
var i,j:longint;
begin
readln(n,m);
for i:=0 to n+1 do
begin
t[i,0]:=1; t[i,m+1]:=1;
end;
for j:=0 to m+1 do
begin
t[0,j]:=1; t[n+1,j]:=1;
end;
for i:=1 to n do
for j:=1 to m do
read(t[i,j]);
fillchar(f,sizeof(f),0);
fillchar(fu,sizeof(fu),false);
fu[0,m,0]:=true;
maxopt:=(1 shl (3*m))-1;
end;
procedure update(i,j,opt,v:longint);
begin
if (not fu[i,j,opt]) or (f[i,j,opt]>v) then
f[i,j,opt]:=v;
fu[i,j,opt]:=true;
end;
function getup(j,opt:longint):longint;
var y:longint;
begin
y:=m-j;
getup:=(opt shr (y*3)) and 7;
end;
function getleft(j,opt:longint):longint;
var y:longint;
begin
y:=m-j;
getleft:=(opt shr (y*3+3)) and 7;
end;
function change(j,opt,e:longint):longint;
var x,y,z:longint;
begin
y:=m-j;
z:=opt and (1 shl (y*3)-1);
x:=opt shr(y*3+3);
change:=((x shl 3)+e) shl (y*3)+z;
end;
procedure sort(var op:longint);
var b:array[0..9,1..2]of longint;
l,k,u:longint;
begin
fillchar(b,sizeof(b),0);
for l:=0 to m do
b[l,1]:=getup(l,op);
k:=2;
for l:=0 to m do
if (b[l,2]=0) and (b[l,1]>2) then
begin
inc(k);
b[l,2]:=k;
for u:=l+1 to m do
if b[l,1]=b[u,1] then b[u,2]:=k;
end;
for l:=0 to m do
if b[l,2]<>0 then op:=change(l,op,b[l,2]);
end;
procedure solve(i,j,opt,v:longint);
var x,y,op,o:longint;
begin
x:=getleft(j,opt);
y:=getup(j,opt);
if t[i,j]=1 then
begin
if (x+y=0) then begin
update(i,j,opt,v);
exit;
end;
end;
if t[i,j]=2 then //1
begin
if (x+y=0) then
begin
op:=opt;
op:=change(j-1,op,1);
update(i,j,op,v);
op:=opt;
op:=change(j,op,1);
update(i,j,op,v);
end else
if (x*y=0) and (x<>2) and (y<>2) then
begin
op:=opt;
if (x=0) then begin
for o:=0 to m do
if getup(o,op)=y then op:=change(o,op,1);
end else begin
for o:=0 to m do
if getup(o,op)=x then op:=change(o,op,1);
end;
sort(op);
op:=change(j,op,0);
op:=change(j-1,op,0);
update(i,j,op,v);
end;
exit;
end;
if t[i,j]=3 then //2
begin
if (x+y=0) then
begin
op:=opt;
op:=change(j-1,op,2);
update(i,j,op,v);
op:=opt;
op:=change(j,op,2);
update(i,j,op,v);
end else
if (x*y=0) and (x<>1) and (y<>1) then
begin
op:=opt;
if (x=0) then begin
for o:=0 to m do
if getup(o,op)=y then op:=change(o,op,2);
end else begin
for o:=0 to m do
if getup(o,op)=x then op:=change(o,op,2);
end;
sort(op);
op:=change(j,op,0);
op:=change(j-1,op,0);
update(i,j,op,v);
end;
exit;
end;
// t[i,j]=0
if (x=0) and (y=0) then
begin
update(i,j,opt,v);
if (t[i,j+1]=0) and (t[i+1,j]=0) then
begin
op:=opt;
op:=change(j,op,7);
op:=change(j-1,op,7);
sort(op);
update(i,j,op,v+1);
end;
exit;
end;
if (x<>0) and (y=0) then
begin
if t[i+1,j]=0 then
begin
update(i,j,opt,v+1);
end;
if t[i,j+1]=0 then
begin
op:=change(j,opt,x);
op:=change(j-1,op,0);
update(i,j,op,v+1);
end;
exit;
end;
if (y<>0) and (x=0) then
begin
if t[i,j+1]=0 then
begin
update(i,j,opt,v+1);
end;
if t[i+1,j]=0 then
begin
op:=change(j,opt,0);
op:=change(j-1,op,y);
update(i,j,op,v+1);
end;
exit;
end;
if (x<>0) and (y<>0) and (x*y<>2) then begin
op:=opt;
if x>y then
begin
for o:=0 to m do
if getup(o,op)=y then op:=change(o,op,y);
end else
begin
for o:=0 to m do
if getup(o,op)=x then op:=change(o,op,x);
end;
sort(op);
op:=change(j,op,0);
op:=change(j-1,op,0);
update(i,j,op,v+1);
end;
end;
procedure main;
var i,j,opt:longint;
begin
for i:=1 to n do
begin
for opt:=0 to maxopt shr 3 do
if fu[i-1,m,opt shl 3] then
solve(i,1,opt,f[i-1,m,opt shl 3]);
for j:=2 to m do
begin
for opt:=0 to maxopt do
if fu[i,j-1,opt] then
solve(i,j,opt,f[i,j-1,opt]);
end;
end;
if fu[n,m,0] then
writeln(f[n,m,0]) else writeln('Impossible');
end;
begin
assign(input,'writing.in');
reset(input);
assign(output,'writing.out');
rewrite(output);
init;
main;
close(input);
close(output);
end.
var
f:array[0..10,1..9,0..2000000]of byte;
fu:array[0..10,1..9,0..2000000]of boolean;
t:array[0..10,0..10]of longint;
maxopt,n,m:longint;
procedure init;
var i,j:longint;
begin
readln(n,m);
for i:=0 to n+1 do
begin
t[i,0]:=1; t[i,m+1]:=1;
end;
for j:=0 to m+1 do
begin
t[0,j]:=1; t[n+1,j]:=1;
end;
for i:=1 to n do
for j:=1 to m do
read(t[i,j]);
fillchar(f,sizeof(f),0);
fillchar(fu,sizeof(fu),false);
fu[0,m,0]:=true;
maxopt:=(1 shl (3*m))-1;
end;
procedure update(i,j,opt,v:longint);
begin
if (not fu[i,j,opt]) or (f[i,j,opt]>v) then
f[i,j,opt]:=v;
fu[i,j,opt]:=true;
end;
function getup(j,opt:longint):longint;
var y:longint;
begin
y:=m-j;
getup:=(opt shr (y*3)) and 7;
end;
function getleft(j,opt:longint):longint;
var y:longint;
begin
y:=m-j;
getleft:=(opt shr (y*3+3)) and 7;
end;
function change(j,opt,e:longint):longint;
var x,y,z:longint;
begin
y:=m-j;
z:=opt and (1 shl (y*3)-1);
x:=opt shr(y*3+3);
change:=((x shl 3)+e) shl (y*3)+z;
end;
procedure sort(var op:longint);
var b:array[0..9,1..2]of longint;
l,k,u:longint;
begin
fillchar(b,sizeof(b),0);
for l:=0 to m do
b[l,1]:=getup(l,op);
k:=2;
for l:=0 to m do
if (b[l,2]=0) and (b[l,1]>2) then
begin
inc(k);
b[l,2]:=k;
for u:=l+1 to m do
if b[l,1]=b[u,1] then b[u,2]:=k;
end;
for l:=0 to m do
if b[l,2]<>0 then op:=change(l,op,b[l,2]);
end;
procedure solve(i,j,opt,v:longint);
var x,y,op,o:longint;
begin
x:=getleft(j,opt);
y:=getup(j,opt);
if t[i,j]=1 then
begin
if (x+y=0) then begin
update(i,j,opt,v);
exit;
end;
end;
if t[i,j]=2 then //1
begin
if (x+y=0) then
begin
op:=opt;
op:=change(j-1,op,1);
update(i,j,op,v);
op:=opt;
op:=change(j,op,1);
update(i,j,op,v);
end else
if (x*y=0) and (x<>2) and (y<>2) then
begin
op:=opt;
if (x=0) then begin
for o:=0 to m do
if getup(o,op)=y then op:=change(o,op,1);
end else begin
for o:=0 to m do
if getup(o,op)=x then op:=change(o,op,1);
end;
sort(op);
op:=change(j,op,0);
op:=change(j-1,op,0);
update(i,j,op,v);
end;
exit;
end;
if t[i,j]=3 then //2
begin
if (x+y=0) then
begin
op:=opt;
op:=change(j-1,op,2);
update(i,j,op,v);
op:=opt;
op:=change(j,op,2);
update(i,j,op,v);
end else
if (x*y=0) and (x<>1) and (y<>1) then
begin
op:=opt;
if (x=0) then begin
for o:=0 to m do
if getup(o,op)=y then op:=change(o,op,2);
end else begin
for o:=0 to m do
if getup(o,op)=x then op:=change(o,op,2);
end;
sort(op);
op:=change(j,op,0);
op:=change(j-1,op,0);
update(i,j,op,v);
end;
exit;
end;
// t[i,j]=0
if (x=0) and (y=0) then
begin
update(i,j,opt,v);
if (t[i,j+1]=0) and (t[i+1,j]=0) then
begin
op:=opt;
op:=change(j,op,7);
op:=change(j-1,op,7);
sort(op);
update(i,j,op,v+1);
end;
exit;
end;
if (x<>0) and (y=0) then
begin
if t[i+1,j]=0 then
begin
update(i,j,opt,v+1);
end;
if t[i,j+1]=0 then
begin
op:=change(j,opt,x);
op:=change(j-1,op,0);
update(i,j,op,v+1);
end;
exit;
end;
if (y<>0) and (x=0) then
begin
if t[i,j+1]=0 then
begin
update(i,j,opt,v+1);
end;
if t[i+1,j]=0 then
begin
op:=change(j,opt,0);
op:=change(j-1,op,y);
update(i,j,op,v+1);
end;
exit;
end;
if (x<>0) and (y<>0) and (x*y<>2) then begin
op:=opt;
if x>y then
begin
for o:=0 to m do
if getup(o,op)=y then op:=change(o,op,y);
end else
begin
for o:=0 to m do
if getup(o,op)=x then op:=change(o,op,x);
end;
sort(op);
op:=change(j,op,0);
op:=change(j-1,op,0);
update(i,j,op,v+1);
end;
end;
procedure main;
var i,j,opt:longint;
begin
for i:=1 to n do
begin
for opt:=0 to maxopt shr 3 do
if fu[i-1,m,opt shl 3] then
solve(i,1,opt,f[i-1,m,opt shl 3]);
for j:=2 to m do
begin
for opt:=0 to maxopt do
if fu[i,j-1,opt] then
solve(i,j,opt,f[i,j-1,opt]);
end;
end;
if fu[n,m,0] then
writeln(f[n,m,0]) else writeln('Impossible');
end;
begin
assign(input,'writing.in');
reset(input);
assign(output,'writing.out');
rewrite(output);
init;
main;
close(input);
close(output);
end.