#include<iostream>
#include<vector>
#include<queue>
using namespace std;
struct Node{
int i;
int j;
int sd;
};
int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
int bfs(vector<vector<char> > &v,int x,int y){
int m=v.size(),n=v[0].size();
vector<vector<bool> > visited(m,vector<bool>(n,false));
queue<Node> Q;
Node node={x,y,0};
Q.push(node),visited[node.i][node.j]=true;
while(!Q.empty()) {
node=Q.front();Q.pop();
if(node.i==m-1&&node.j==n-1)
return node.sd;
for(int i=0;i<4;i++){
Node next={node.i+dx[i],node.j+dy[i],node.sd+1};
if(next.i>=0&&next.i<m&&next.j>=0&&next.j<n&&v[next.i][next.j]!='1'&&visited[next.i][next.j]==false){
Q.push(next);
visited[next.i][next.j]=true;
}
}
}
}
bool isRepeat(vector<Node> &Path, int i, int j){
for(int k=0;k<Path.size(); k++)
if(Path[k].i==i&&Path[k].j==j)
return true;
return false;
}
priority_queue<int,vector<int>,less<int> > sd;
void dfs(vector<vector<char> > &v, int si,int sj,int ei,int ej,vector<Node> &Path,int ans){
Node node={si,sj,ans};
Path.push_back(node);
if(si==ei&&sj==ej){
if(v[si][sj]=='#')
ans++;
sd.push(ans);
}else{
int m=v.size(), n=v[0].size();
for(int k=0; k<4; k++){
int nexti=si+dx[k],nextj=sj+dy[k];
if(nexti<0 || nexti>=m) continue;
if(nextj<0 || nextj>=n) continue;
if(v[nexti][nextj]=='1') continue;
if( isRepeat(Path,nexti,nextj)==true ) continue;
if(v[nexti][nextj]=='#')
ans++;
dfs(v, nexti,nextj,ei,ej,Path,ans);
if(v[nexti][nextj]=='#')
ans--;
}
}
Path.pop_back();
}
int main(){
int m,n;
cin>>m>>n;
vector<vector<char> > v(m,vector<char>(n));
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
cin>>v[i][j];
cout<<bfs(v,0,0)<<" ";
vector<Node> Path;
dfs(v,m-1,n-1,0,0,Path,0);
cout<<sd.top()<<endl;
}