#include <bits/stdc++.h>
using namespace std;
template <class T1, class T2>
inline istream& operator>>(istream& fin, pair<T1, T2>& pr) {
  fin >> pr.first >> pr.second;
  return fin;
}
template <class T0, class T1, class T2>
inline istream& operator>>(istream& fin, tuple<T0, T1, T2>& t) {
  fin >> get<0>(t) >> get<1>(t) >> get<2>(t);
  return fin;
}
template <class T>
inline istream& operator>>(istream& fin, vector<T>& a) {
  for (auto& u : a) fin >> u;
  return fin;
}
template <class T, size_t n>
inline istream& operator>>(istream& fin, array<T, n>& a) {
  for (auto& u : a) fin >> u;
  return fin;
}
template <class FwdIter>
inline auto dump(FwdIter first, FwdIter last, const char* dlm = " ") -> void {
  copy(first, last,
       ostream_iterator<typename iterator_traits<FwdIter>::value_type>(cout,
                                                                       dlm));
}
template <typename T>
vector<T>& operator--(vector<T>& a) {
  for (auto& i : a) --i;
  return a;
}
typedef struct {
  size_t init;
  size_t dot;
  size_t blk;
} value_t;
inline bool operator!=(const value_t& a, const value_t& b) {
  return a.init != b.init || a.dot != b.dot || a.blk != b.blk;
}
std::ostream& operator<<(std::ostream& out, const value_t& a) {
  out << "{" << a.init << ", " << a.dot << ", " << a.blk << "}";
  return out;
}
inline size_t getval(const size_t k, const value_t& v) {
  if (!v.blk) return (v.init + v.dot + k - 1) / k;
  if (v.init < k)
    return 1 + max((v.blk + k - 1) / k, (v.dot + v.blk + k - 1) / k);
  return max((v.blk + k - 1) / k, (v.dot + v.init + v.blk + k - 1) / k);
}
inline value_t add(const value_t& v, const char c) {
  if (c == '.')
    return v.blk ? value_t({v.init, v.dot + 1, v.blk})
                 : value_t({v.init + 1, v.dot, v.blk});
  return value_t({v.init, v.dot, v.blk + 1});
}
int main(const int argc, char* argv[]) {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  size_t n, m, k;
  cin >> n >> m >> k;
  vector<string> a(n);
  cin >> a;
  const size_t inf = n * m + 100;
  vector<vector<value_t>> dist(n, vector<value_t>(m, {inf, inf}));
  const auto comp = [k](const value_t& a, const value_t& b) {
    return getval(k, a) < getval(k, b);
  };
  const auto comp_node = [comp](const pair<pair<size_t, size_t>, value_t>& a,
                                const pair<pair<size_t, size_t>, value_t>& b) {
    return comp(b.second, a.second);
  };
  priority_queue<pair<pair<size_t, size_t>, value_t>,
                 vector<pair<pair<size_t, size_t>, value_t>>,
                 decltype(comp_node)>
      heap(comp_node);
  for (size_t i = 0; i < n && heap.empty(); ++i)
    for (size_t j = 0; j < m && heap.empty(); ++j)
      if (a[i][j] == 'S') {
        a[i][j] = '.';
        dist[i][j] = {0, 0};
        heap.push({{i, j}, {0, 0, 0}});
        break;
      }
  while (!heap.empty()) {
    const auto pr = heap.top();
    heap.pop();
    const auto i = pr.first.first;
    const auto j = pr.first.second;
    const auto d = pr.second;
    if (dist[i][j] != pr.second) continue;
    if (0 < i) {
      const auto e = add(d, a[i - 1][j]);
      if (comp(e, dist[i - 1][j])) heap.push({{i - 1, j}, dist[i - 1][j] = e});
    }
    if (i + 1 < n) {
      const auto e = add(d, a[i + 1][j]);
      if (comp(e, dist[i + 1][j])) heap.push({{i + 1, j}, dist[i + 1][j] = e});
    }
    if (0 < j) {
      const auto e = add(d, a[i][j - 1]);
      if (comp(e, dist[i][j - 1])) heap.push({{i, j - 1}, dist[i][j - 1] = e});
    }
    if (j + 1 < m) {
      const auto e = add(d, a[i][j + 1]);
      if (comp(e, dist[i][j + 1])) heap.push({{i, j + 1}, dist[i][j + 1] = e});
    }
  }
  value_t out = {inf, inf, inf};
  for (size_t i = 0; i < n; ++i) {
    if (comp(dist[i][0], out)) out = dist[i][0];
    if (comp(dist[i][m - 1], out)) out = dist[i][m - 1];
  }
  for (size_t j = 0; j < m; ++j) {
    if (comp(dist[0][j], out)) out = dist[0][j];
    if (comp(dist[n - 1][j], out)) out = dist[n - 1][j];
  };
  cout << getval(k, out);
  return EXIT_SUCCESS;
}
