/*
* Problem :: 17836 / 공주님을 구해라!
*
* Kind :: BFS
*
* Insight
* - 그람을 갖고 있지 않으면 벽을 못 부수지만
* 그람을 가지고 있으면 벽을 부수고 갈 수 있다
* + 현재 그람을 가지고 있는지 그렇지 않은지를 주의하며 BFS 를 돌리자
* dp[i][j][GRAM] = 그람을 가지고 (i,j) 위치에 도달하는 최소시간
* 초기값은 -1(도달하지 못한 경우)
* dp[i][j][NOGRAM] = 그람을 가지지 않고 (i,j) 위치에 도달하는 최소시간
* 초기값은 -1(도달하지 못한 경우)
*
* Point
* - '이내' = '안(일정한 표준이나 한계를 넘지 않은 정도'
* + 20자 이내 = (한 자에서부터) 이십 자까지
* + T시간 이내 = (한 시간에서부터) T 시간까지
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
#define endl '\n'
// Set up : Global Variables
struct Point { int y, x, hasGram; };
enum { NOGRAM, GRAM};
int dy[4] = {+1, 0, 0, -1};
int dx[4] = {0, +1, -1, 0};
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N, M, T;
cin >> N >> M >> T;
int A[N+1][M+1];
for (int i=1; i<=N; i++)
for (int j=1; j<=M; j++)
cin >> A[i][j];
// Process
queue<Point> que;
int dp[N+1][M+1][2];
memset(dp, -1, sizeof(dp));
/* 초기화 - (1,1) 위치 */
dp[1][1][NOGRAM] = 0;
que.push({1, 1, NOGRAM});
/* BFS */
while (not(que.empty())) {
int cy = que.front().y; /* 현재 y 좌표 */
int cx = que.front().x; /* 현재 x 좌표 */
int hasGram = que.front().hasGram; /* 현재 그람 소유 여부 */
que.pop();
/* 현재 위치에 그람이 있다면 */
if (A[cy][cx] == 2) {
hasGram = true; /* 줍줍 */
/* 이제부터는 그람으로 벽을 부수면서 전진 */
dp[cy][cx][GRAM] = dp[cy][cx][NOGRAM];
}
/* 공주님 발견 */
if (cy == N && cx == M) continue;
for (int i=0; i<4; i++) {
int ny = cy + dy[i]; /* 다음 y 좌표 */
int nx = cx + dx[i]; /* 다음 x 좌표 */
/* 다음 (ny,nx) 위치가 유효하다면 */
if (ny >= 1 && ny <= N && nx >= 1 && nx <= M) {
/* 그람을 가지고 있다면 */
if (hasGram) {
/* (ny,nx) 위치에 방문하지 않았거나 더 빨리 도착하는 경우라면 */
if (dp[ny][nx][GRAM] == -1
|| dp[ny][nx][GRAM] > dp[cy][cx][GRAM]+1)
{
dp[ny][nx][GRAM] = dp[cy][cx][GRAM]+1; /* dp 갱신 */
que.push({ny, nx, GRAM}); /* que 에 추가 */
}
/* 그람을 가지고 있지 않다면 */
} else {
/* (ny,nx) 위치가 벽이 아니며 */
if (A[ny][nx] != 1) {
/* (ny,nx) 위치에 방문하지 않았거나 더 빨리 도착하는 경우라면 */
if (dp[ny][nx][NOGRAM] == -1
|| dp[ny][nx][NOGRAM] > dp[cy][cx][NOGRAM]+1)
{
dp[ny][nx][NOGRAM] = dp[cy][cx][NOGRAM]+1; /* dp 갱신 */
que.push({ny, nx, NOGRAM}); /* que 에 추가 */
}
}
}
}
}
}
int INF = T+1;
int t1 = dp[N][M][NOGRAM]; /* 그람없이 공주님을 발견할 수 있는 최단시간 */
if (t1 == -1) { t1 = INF; } /* 발견할 수 없다면 INF 시간 */
int t2 = dp[N][M][GRAM]; /* 그람있시 공주님을 발견할 수 있는 최단시간 */
if (t2 == -1) { t2 = INF; } /* 발견할 수 없다면 INF 시간 */
bool isPossible = min(t1, t2) <= T;
// Control : Output
cout << ((isPossible) ? to_string(min(t1, t2)) : "Fail") << endl;
}
// Helper Functions
/* None */