#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
const int rp = 666666;
const bool debug = 1;
const int Mod = 1e9 + 7;
int n, m, k;
long long ans;
int limit[12][12];
int able[12][12][12];
vector<int> newColor;
int x[12];
int y[12];
bool used[12];
void dfs(int nowX, int nowY, int nextNew, long long Times) {
  if (nowY >= m) {
    nowX++;
    nowY = 0;
  }
  if (nowX >= n) {
    ans += Times;
    if (ans >= Mod) ans -= Mod;
    return;
  }
  for (int c = 1; c <= k; c++) {
    if (!able[nowX][nowY][c]) continue;
    if (limit[nowX][nowY] && limit[nowX][nowY] != c) continue;
    if (!used[c] && c != newColor[nextNew]) continue;
    if (x[c] != -1 && x[c] <= nowX && y[c] <= nowY) continue;
    int tx = x[c], ty = y[c];
    x[c] = nowX, y[c] = nowY;
    if (!used[c]) {
      used[c] = true;
      dfs(nowX, nowY + 1, nextNew + 1, Times * (newColor.size() - nextNew));
      used[c] = false;
    } else {
      dfs(nowX, nowY + 1, nextNew, Times);
    }
    x[c] = tx, y[c] = ty;
  }
}
signed main() {
  ios::sync_with_stdio(false);
  cin >> n >> m >> k;
  if (n + m - 1 > k) {
    cout << "0" << endl;
    return 0;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      cin >> limit[i][j];
      used[limit[i][j]] = true;
    }
  }
  for (int i = 1; i <= k; i++) {
    if (!used[i]) newColor.push_back(i);
  }
  memset(able, 1, sizeof(able));
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      for (int c = 1; c <= k; c++) {
        for (int I = 0; I < n; I++) {
          for (int J = 0; J < m; J++) {
            if (I <= i && J <= j && limit[I][J] == c) able[i][j][c] = false;
            if (I >= i && J >= j && limit[I][J] == c) able[i][j][c] = false;
          }
        }
        if (limit[i][j] == c) able[i][j][c] = true;
      }
    }
  }
  memset(x, -1, sizeof(x));
  dfs(0, 0, 0, 1);
  cout << ans << endl;
  return 0;
}
