use std::io::{self, Stdin};
use std::str::{self, FromStr};
use std::error::Error;
use std::cmp::*;
use std::collections::VecDeque;
fn exec() {
    let mut sc = Scanner::new();
    let (h, w, k): (usize, usize, i64) = (sc.ne(), sc.ne(), sc.ne());
    let mut fld = Vec::new();
    for _ in 0..h {
        let s = sc.ne::<String>().into_bytes();
        fld.push(s);
    }
    let f = |y: usize, x: usize| -> i64 {
        let ymin = min(y, h - y - 1);
        let xmin = min(x, w - x - 1);
        min(xmin, ymin) as i64
    };
    let mut score = vec![vec![0;w];h];
    for i in 0..h {
        for j in 0..w {
            let cost = f(i, j);
            score[i][j] = (cost + k - 1) / k;
        }
    }
    let mut que = VecDeque::new();
    const INF: i64 = 1000000000;
    let mut dist = vec![vec![INF; w]; h];
    for i in 0..h {
        for j in 0..w {
            if fld[i][j] == b'S' {
                dist[i][j] = 0;
                que.push_back((j as i32, i as i32));
            }
        }
    }
    const DX: [i32; 4] = [-1, 0, 0, 1];
    const DY: [i32; 4] = [0, -1, 1, 0];
    while let Some((x, y)) = que.pop_front() {
        let cd = dist[y as usize][x as usize];
        for i in 0..4 {
            let nx = x + DX[i];
            let ny = y + DY[i];
            if nx < 0 || ny < 0 || nx >= (w as i32) || ny >= (h as i32) {
                continue;
            }
            if dist[ny as usize][nx as usize] < INF {
                continue;
            }
            if fld[ny as usize][nx as usize] == b'#' {
                continue;
            }
            dist[ny as usize][nx as usize] = cd + 1;
            que.push_back((nx, ny));
        }
    }
    let mut ans = INF;
    for i in 0..h {
        for j in 0..w {
            ans = min(ans, score[i][j] + max(1, (dist[i][j] + k - 1) / k));
        }
    }

    println!("{}", ans);
}

fn main() {
    const STACK: usize = 16 * 1024 * 1024;
    let _ = std::thread::Builder::new()
        .stack_size(STACK)
        .spawn(|| { exec(); })
        .unwrap()
        .join()
        .unwrap();
}

#[allow(dead_code)]
struct Scanner {
    stdin: Stdin,
    id: usize,
    buf: Vec<u8>,
}

#[allow(dead_code)]
impl Scanner {
    fn new() -> Scanner {
        Scanner {
            stdin: io::stdin(),
            id: 0,
            buf: Vec::new(),
        }
    }
    fn next_line(&mut self) -> Option<String> {
        let mut res = String::new();
        match self.stdin.read_line(&mut res) {
            Ok(0) => None,
            Ok(_) => Some(res),
            Err(why) => panic!("error in read_line: {}", why.description()),
        }
    }
    fn next<T: FromStr>(&mut self) -> Option<T> {
        while self.buf.len() == 0 {
            self.buf = match self.next_line() {
                Some(r) => {
                    self.id = 0;
                    r.trim().as_bytes().to_owned()
                }
                None => return None,
            };
        }
        let l = self.id;
        assert!(self.buf[l] != b' ');
        let n = self.buf.len();
        let mut r = l;
        while r < n && self.buf[r] != b' ' {
            r += 1;
        }
        let res = match str::from_utf8(&self.buf[l..r])
                  .ok()
                  .unwrap()
                  .parse::<T>() {
            Ok(s) => Some(s),
            Err(_) => {
                panic!("parse error, {:?}",
                       String::from_utf8(self.buf[l..r].to_owned()))
            }
        };
        while r < n && self.buf[r] == b' ' {
            r += 1;
        }
        if r == n {
            self.buf.clear();
        } else {
            self.id = r;
        }
        res
    }
    fn ne<T: FromStr>(&mut self) -> T {
        self.next::<T>().unwrap()
    }
}


Measured memory_bytes: 20860