//暴力的代码:
//Acwing通过了 3/10个数据
//蓝桥杯官网:通过率: 50%。共8个测试用例,4个通过,4个未通过
// #include <bits/stdc++.h>
// #define int long long
// using namespace std;
// const int N = 60;
// const long long M = 1e9+7;
// int n,m,k;
// int p[N][N];
// int dx[2] = {1, 0};
// int dy[2] = {0, 1};
// priority_queue<int> q;
// int res;
// //z就是目前我选了多少个宝贝
// void dfs(int x, int y, int z){
// if(z == k && x == n && y == m){
// res = (res + 1) % M;
// return;
// }
// if(x>n || z>k || y>m) return;
// for(int i=0;i<2;i++){
// int xx = x + dx[i], yy = y + dy[i];
// //如果xx和yy坐标越界,我们只能让for循环continue不能让其break
// if(xx<1 || xx>n || yy<1 || yy>m) continue;
// bool tr = true;
// if(!q.empty() && q.top() < p[xx][yy]){
// q.push(p[xx][yy]);
// dfs(xx, yy, z+1);
// q.pop();
// }
// dfs(xx,yy,z);
// }
// }
// signed main()
// {
// // 请在此输入您的代码
// cin>>n>>m>>k;
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++){
// cin>>p[i][j];
// }
// }
// q.push(-1);
// dfs(1,1,0);
// q.push(p[1][1]);
// dfs(1,1,1);
// cout<<res<<endl;
// return 0;
// }
//AC代码
//dfs+记忆化搜索
//由于我们进行的是记忆化搜索,所以要对每一种状态的值都要精确表示出来
//因此,我们不能使用priority_queue<int> q来求出我们的最大值,我们应该在dfs的时候加上一个参数,来记录目前我们的最大值
//并且再新建一个状态数组,表示我们是否有访问这个状态
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 60;
const long long M = 1e9+7;
int n,m,k;
int p[N][N];
int dx[2] = {1, 0};
int dy[2] = {0, 1};
// priority_queue<int> q;
int dp[N][N][15][15];
// int res;//这里res我们不能用全局数组
//z就是目前我选了多少个宝贝, mx表示目前的最大值
int dfs(int x, int y, int z, int mx){
if(x == n && y == m) return z == k;//这个是我们的终止状态,如果z==k,我们就返回1,否则返回0
//访问记忆化数组,看看是否求过这个状态
if(dp[x][y][z][mx] != -1) return dp[x][y][z][mx];
//这里不能判断z>k,因为如果我们的z==k,但是我们的路径还是可以继续走下去的
// if(z > k) return;
//这里res我们不能用全局数组
long long res = 0;
for(int i=0;i<2;i++){
int xx = x + dx[i], yy = y + dy[i];
//如果xx和yy坐标越界,我们只能让for循环continue不能让其break
if(xx<1 || xx>n || yy<1 || yy>m) continue;
//表示我们的最大值小于p[xx][yy],我们就可以选这个宝贝
if(mx < p[xx][yy] && z < k){//之所以z<k要放到这里,是因为我们如果已经提前选好了k个宝贝,我们后面就可以都不选,但是这个也算是一种路径,所以得加上
res = (res + dfs(xx, yy, z+1, p[xx][yy])) % M;
}
//表示不拿这个宝贝,这里的情况包含了两种:
//1、我们的最大值大于p[xx][yy],我们可以不拿这个宝贝
//2、我们的最大值小于p[xx][yy],我们拿不了这个宝贝
res = (res + dfs(xx,yy,z, mx)) % M;
}
dp[x][y][z][mx] = res;//记录这个状态到记忆化数组里面
return res;
}
signed main()
{
// 请在此输入您的代码
cin>>n>>m>>k;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>p[i][j];
p[i][j]++;//因为我们计算的是路径,和权值无关,所以我们把所有的权值+1。杜绝0的情况
}
}
//初始化dp数组为-1
memset(dp, -1, sizeof dp);
//注意:我们这里输入的最大值包含0的情况,所以我们要保证在dp数组中我们的最小值是1的情况
cout<<(dfs(1,1,0,0) + dfs(1,1,1,p[1][1])) % M<<endl;
return 0;
}