// Original C++ solution (slower):
#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>

#include <ext/pb_ds/tree_policy.hpp>



using namespace std;

using namespace __gnu_pbds;



#define fi first

#define se second

#define mp make_pair

#define pb push_back

#define fbo find_by_order

#define ook order_of_key



typedef long long ll;

typedef pair<int,int> ii;

typedef vector<ll> vi;

typedef long double ld; 

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;

typedef set<int>::iterator sit;

typedef map<int,int>::iterator mit;

typedef vector<int>::iterator vit;



char a[801][801];

int h,w,k;

int dx[4] = {1,-1,0,0};

int dy[4] = {0,0,1,-1};



bool isvalid(int x, int y)

{

	return (x>=0&&x<h&&y>=0&&y<w);

}



bool isexit(int x, int y)

{

	return (x==0||x==h-1||y==0||y==w-1);

}



int dist[801][801];

const int INF = int(1e9);



int main()

{

	ios_base::sync_with_stdio(0); cin.tie(0);

	cin>>h>>w>>k;

	ii s;

	for(int i=0;i<h;i++)

	{

		for(int j=0;j<w;j++)

		{

			cin>>a[i][j];

			if(a[i][j]=='S') s=mp(i,j);

		}

	}

	for(int i=0;i<h;i++)

	{

		for(int j=0;j<w;j++)

		{

			dist[i][j]=INF;

		}

	}

	queue<ii> q;

	q.push(s);

	dist[s.fi][s.se]=0;

	while(!q.empty())

	{

		ii tmp=q.front(); q.pop();

		for(int i=0;i<4;i++)

		{

			int x=tmp.fi+dx[i]; int y=tmp.se+dy[i];

			if(isvalid(x,y))

			{

				if(a[x][y]=='#') continue;

				if(dist[x][y]>=INF)

				{

					dist[x][y]=dist[tmp.fi][tmp.se]+1;

					q.push(mp(x,y));

				}

			}

		}

	}

	int ans=INF;

	vector<ii> vec;

	for(int i=0;i<h;i++)

	{

		for(int j=0;j<w;j++)

		{

			if(isexit(i,j)) ans=min(ans,dist[i][j]);

			if(dist[i][j]<=k)

			{

				vec.pb(mp(i,j));

			}

		}

	}

	if(ans<=k)

	{

		cout<<1<<'\n';

		return 0;

	}

	for(int i=0;i<h;i++)

	{

		for(int j=0;j<w;j++)

		{

			dist[i][j]=INF;

			if(isexit(i,j))

			{

				dist[i][j]=0;

				q.push(mp(i,j));

			}

		}

	}

	while(!q.empty())

	{

		ii tmp=q.front(); q.pop();

		for(int i=0;i<4;i++)

		{

			int x=tmp.fi+dx[i]; int y=tmp.se+dy[i];

			if(isvalid(x,y))

			{

				if(dist[x][y]>=INF)

				{

					dist[x][y]=dist[tmp.fi][tmp.se]+1;

					q.push(mp(x,y));

				}

			}

		}

	}

	for(int i=0;i<vec.size();i++)

	{

		ans=min(ans,dist[vec[i].fi][vec[i].se]);

	}

	cout<<(ans+k-1)/k+1<<'\n';

}


// Optimized solution to the same problem (faster):
#include<cstdio>

#include<cstring>

#include<algorithm>

#include<cmath>

#include<vector>

#include<queue>

#define SF scanf

#define PF printf

#define Mkp make_pair

#define MAXN 810

using namespace std;

typedef pair<int,int> pii;

char s[MAXN][MAXN];

int h,w,k;

int vis[MAXN][MAXN],dist[MAXN][MAXN];

queue<pair<int,int> > q;

bool allow(int x,int y){

	if(x<=0||y<=0||x>h||y>w||s[x][y]=='#'||vis[x][y]==1)

		return 0;

	return 1;	

}

int t[6][4]={{0,1},{0,-1},{1,0},{-1,0}};

void bfs(int x,int y){

	vis[x][y]=1;

	q.push(Mkp(x,y));

	while(!q.empty()){

		pii newq=q.front();

		q.pop();

		if(dist[newq.first][newq.second]==k)

			break;

		for(int i=0;i<4;i++){

			int xx=newq.first+t[i][0];

			int yy=newq.second+t[i][1];

			if(allow(xx,yy)==0)

				continue;

			vis[xx][yy]=1;

			dist[xx][yy]=dist[newq.first][newq.second]+1;

			q.push(Mkp(xx,yy));

		}

	}

}

int mindist(int x,int y){

	return min(min((x+k-2)/k,(y+k-2)/k),min((h-x+k-1)/k,(w-y+k-1)/k));	

}

int main(){

	int stx,sty;

	SF("%d%d%d",&h,&w,&k);

	for(int i=1;i<=h;i++)

		SF("%s",s[i]+1);

	for(int i=1;i<=h;i++)

		for(int j=1;j<=w;j++)

			if(s[i][j]=='S'){

				stx=i;

				sty=j;

			}

	bfs(stx,sty);

	int ans=1+mindist(stx,sty);

	for(int i=1;i<=h;i++)

		for(int j=1;j<=w;j++)

			if(vis[i][j]==1){

				ans=min(ans,1+mindist(i,j));

			}

	PF("%d",ans);

}

// Fastest known solution for this problem: