#include<bits/stdc++.h>
using namespace std;


int n,cnt;//n:矩阵大小;cnt:路线总数 
bool tag[100][100];//记录当前节点是否走过:初始为false; 
int dir[][2]={
   {
   1,0},{
   0,-1},{
   -1,0},{
   0,1}};//方向向量 
int print[100][2];//记录路径坐标 

void dfs(int x,int y,int k)//x,y坐标,k:当前节点所在层数 
{
   	
	if(x==n&&y==n){
   //当x,y满足输出条件 
		cnt++;//找到一条路 
		for(int i=0;i<k;i++){
   //输出每层节点坐标 
			cout<<'('<<print[i][0]<<','<<print[i][1]<<')';
			if(i==k-1)
				cout<<endl;
		}
		return ;//返回 
	}
	
	for(int i=0;i<4;i++){
   //沿四个方向搜索 
		int ix=x+dir[i][0];
		int iy=y+dir[i][1];
		if(tag[ix][iy]||ix<1||iy<1||ix>n||iy>n){
   
			continue;//边界条件 
		}
		print[k][0]=ix;//记录当前节点坐标 
		print[k][1]=iy;
		tag[ix][iy]=true;//当前节点走过 
		dfs(ix,iy,k+1);//递归调用 
		tag[ix][iy]=false;//回溯要修改当前节点的状态 
	}
}

int main(){
   
	cin>>n;
	tag[1][1]=true;//起点位置 
	print[0][0]=1;//起点坐标 
	print[0][1]=1;
	dfs(1,1,1);//深度优先搜索 
	cout<<cnt;
}

#include<bits/stdc++.h>//[BFS]
using namespace std;

int dir[][2]={
   {
   1,0},{
   -1,0},{
   0,1},{
   0,-1}};//方向向量 
int n,m;//终点坐标 
const int N=100;
int map1[N][N];//定义的搜索图 

struct node{
   //点的坐标 
	int x;
	int y;	
};
queue<node> que;//queue队列 
int foot[N][N];//走过的要标记起来 
int bfs(){
   
	//初始化
	que.push({
   0,0});
	foot[0][0]=0; //初始步数为0 
	//队列不为空
	while(que.size()){
   
		//首先出队
		node temp=que.front();
		que.pop();
		//遍历四个方向
		for(int i=0;i<4;i++){
   //四个方向搜索 
			int ix=temp.x+dir[i][0];
			int iy=temp.y+dir[i][1];
			if(ix<0||iy<0||ix>=n||iy>=m||foot[ix][iy]!=-1||map1[ix][iy]==1){
   
				continue;
			}
			
			//入队
			que.push({
   ix,iy});
			foot[ix][iy]=foot[temp.x][temp.y]+1;//到当前节点的步数 
			
			//结束条件
			if(ix==n-1&&iy==m-1){
   
				return foot[ix][iy];//输出步数 
			} 
		} 
	} 
}

int main(){
   
	cin>>n>>m;
	for(int i=0;i<n;i++){
   
		for(int j=0;j<m;j++){
   
			cin>>map1[i][j];
		}
	}
	memset(foot,-1,sizeof(foot));//初始化所有节点为-1; 
	cout<<bfs()<<endl;
}