/* ==================================================================================================================
 * CodeIQ
 *
 * K_Yaguchi
 * 2016.11.05
 ================================================================================================================== */

#include <stdio.h>
//#include <ctype.h>
//#include <conio.h>


//////////////////////////////////////////////////
//【実力判定：Sランク】まっすぐ行こう　 スキルチェック部さんの問題に挑戦中！
//https://c...content-available-to-author-only...q.jp/challenge/2516
#define MAXNODE 64 // 最大ノード

// ノード
typedef struct _node {
	char isnode; // 自身のノードの種類 '.' or '#'
	int isgoal;  // 1=ゴール
	int cost   ; // 移動コスト -1=初期値
} NODE;

// 探索用データ
typedef struct _trac {
	int cost; // 曲がった数
	int vect; // 探索方向 0=初期値 1=top 2=bottom 3=left 4=right
	int row;  // 探索すべき行
	int col;  // 探索すべき列
} TRAC;

// 探索
// 戻り値：ゴールした=1
static int route(NODE node[MAXNODE][MAXNODE], int m, int n, TRAC* trac, int* goal, int* mincost)
{
	int r=0,c=0;
	int ret=0;
	TRAC t={0};
	int istop=0,isbottom=0,isleft=0,isright=0; // 次に移動できるノード
	int i=0;
	int vect=0;

	r = trac->row;
	c = trac->col;
	vect = trac->vect;

	if( node[r][c].cost < 0 || node[r][c].cost > trac->cost)
		node[r][c].cost = trac->cost;

	// ゴール
	if( node[r][c].isgoal )
	{
		if( *mincost < 0 || trac->cost < *mincost )
			*mincost = trac->cost;
		(*goal)++;
/*
		for(int y=0;y<m;y++)
		{
			printf("\n");
			for(int x=0;x<n;x++)
			{
				if( node[y][x].cost >= 0 )
					printf("%d", node[y][x].cost);
				else
					printf("%c", node[y][x].isnode);
			}
		}
*/
		return 1;
	}

	// 次に移動できるノード
	istop    = (int)( r > 0 && node[r-1][c].isnode == '.' && trac->vect != 2 && (node[r-1][c].cost < 0 || node[r-1][c].cost > trac->cost) );
	isbottom = (int)( r < m && node[r+1][c].isnode == '.' && trac->vect != 1 && (node[r+1][c].cost < 0 || node[r+1][c].cost > trac->cost) );
	isleft   = (int)( c > 0 && node[r][c-1].isnode == '.' && trac->vect != 4 && (node[r][c-1].cost < 0 || node[r][c-1].cost > trac->cost) );
	isright  = (int)( c < n && node[r][c+1].isnode == '.' && trac->vect != 3 && (node[r][c+1].cost < 0 || node[r][c+1].cost > trac->cost) );

	for(i=0; i<4; i++)
	{
		if( vect == 0 || vect == 1 )
		{
			// 上へ
			if( istop )
			{
				t = *trac;
				if( t.vect != 0 && t.vect != 1)
					t.cost++;
				t.vect = 1;
				t.row--;
				ret = route(node, m, n, &t, goal, mincost);
			}
			vect = 2;
		}
		else if( vect == 2 )
		{
			// 下へ
			if( isbottom )
			{
				t = *trac;
				if( t.vect != 0 && t.vect != 2)
					t.cost++;
				t.vect = 2;
				t.row++;
				ret = route(node, m, n, &t, goal, mincost);
			}
			vect = 3;
		}
		else if( vect == 3 )
		{
			// 左へ
			if( isleft )
			{
				t = *trac;
				if( t.vect != 0 && t.vect != 3)
					t.cost++;
				t.vect = 3;
				t.col--;
				ret = route(node, m, n, &t, goal, mincost);
			}
			vect = 4;
		}
		else if( vect == 4 )
		{
			// 右へ
			if( isright )
			{
				t = *trac;
				if( t.vect != 0 && t.vect != 4)
					t.cost++;
				t.vect = 4;
				t.col++;
				ret = route(node, m, n, &t, goal, mincost);
			}
			vect = 1;
		}
	}

	return ret;
}

int main(void)
{
	int m=0,n=0;
	int r=0,c=0;
	char line[MAXNODE+2]="";
	NODE node[MAXNODE][MAXNODE]={0};
	TRAC trac={0};
	int cost=-1;
	int goal=0;

	// m=行数 n=マス数
	scanf("%d %d\n", &m, &n);
	for(r=0; r<m; r++)
	{
		fgets(line, sizeof(line), stdin);
		for(c=0; c<n; c++)
		{
			node[r][c].isnode = line[c];
			node[r][c].cost   = -1;
		}
	}

	trac.row = m-1; // スタート位置
	trac.col = n-1;
	node[0][0].isgoal = 1; // ゴール位置

	// 探索
	route(node, m, n, &trac, &goal, &cost);

	printf("%d\n", cost);
	printf("経路数:%d 最小コスト:%d\n", goal, cost);
//	getch();
	return 0;
}
