#include <bits/stdc++.h>
using namespace std;
clock_t __stt;
inline void TStart() { __stt = clock(); }
inline void TReport() {
  printf("\nTaken Time : %.3lf sec\n",
         (double)(clock() - __stt) / CLOCKS_PER_SEC);
}
template <typename T>
T MIN(T a, T b) {
  return a < b ? a : b;
}
template <typename T>
T MAX(T a, T b) {
  return a > b ? a : b;
}
template <typename T>
T ABS(T a) {
  return a > 0 ? a : (-a);
}
template <typename T>
void UMIN(T &a, T b) {
  if (b < a) a = b;
}
template <typename T>
void UMAX(T &a, T b) {
  if (b > a) a = b;
}
const int MOD = 998244353;
int n, a[2005][2005], f[2005][2005], C[2005][2005], fac[2005], cr[2005], res;
bool got[2005], gotu[2005];
struct BIT {
  int arr[2005];
  void init() { memset(arr, 0, sizeof(arr)); }
  void add(int p, int v) {
    ++p;
    while (p <= n) {
      arr[p] += v;
      p += (p & (-p));
    }
  }
  int sum(int p) {
    ++p;
    int r = 0;
    while (p) {
      r += arr[p];
      p -= (p & (-p));
    }
    return r;
  }
} G[4];
int gs(int d) { return 2 * (int)gotu[d] + (int)got[d]; }
int main() {
  int i, j, k, cdd;
  scanf("%d", &n);
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n; ++j) {
      scanf("%d", &a[i][j]);
      --a[i][j];
    }
  }
  for (i = 0; i <= n; ++i) C[i][0] = 1;
  for (i = 1; i <= n; ++i) {
    for (j = 1; j <= n; ++j) {
      C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % (long long)MOD;
    }
  }
  fac[0] = 1;
  for (i = 1; i <= n; ++i) {
    fac[i] = (long long)fac[i - 1] * (long long)i % (long long)MOD;
  }
  f[0][0] = 1;
  for (i = 1; i <= n; ++i) {
    f[i][0] = fac[i];
    for (j = 1; j < i; ++j) {
      f[i][j] = (long long)f[i - 1][j] * (long long)(i - j) % (long long)MOD;
      f[i][j] += (long long)f[i - 1][j - 1] * (long long)j % (long long)MOD;
      f[i][j] %= MOD;
    }
    if (i > 1)
      f[i][i] =
          (long long)f[i - 1][i - 2] * (long long)(i - 1) % (long long)MOD;
  }
  for (i = 0; i < n; ++i) {
    int dw = 1;
    for (j = i + 1; j < n; ++j) {
      dw = (long long)dw * (long long)f[n][n] % (long long)MOD;
    }
    memset(got, 0, sizeof(got));
    if (i)
      for (j = n - 1; j >= 0; --j) {
        cr[j] = 0;
        if (got[a[i - 1][j]]) ++cr[j];
        if (got[a[i][j]]) ++cr[j];
        got[a[i][j]] = 1;
        got[a[i - 1][j]] = 1;
        if (j < n - 1) cr[j] += cr[j + 1];
      }
    memset(got, 0, sizeof(got));
    memset(gotu, 0, sizeof(gotu));
    for (j = 0; j < 4; ++j) G[j].init();
    for (j = 0; j < n; ++j) G[0].add(j, 1);
    for (j = 0; j < n - 1; ++j) {
      if (i) {
        G[gs(a[i - 1][j])].add(a[i - 1][j], -1);
        gotu[a[i - 1][j]] = 1;
        G[gs(a[i - 1][j])].add(a[i - 1][j], 1);
      }
      if (i) {
        cdd = G[0].sum(a[i][j] - 1);
        int crs = cr[j + 1] + (int)(!gotu[a[i][j]]) - 1;
        res += (long long)cdd * (long long)dw % (long long)MOD *
               (long long)f[n - j - 1][crs] % (long long)MOD;
        res %= MOD;
        cdd = G[2].sum(a[i][j] - 1);
        if (a[i - 1][j] < a[i][j] && !got[a[i - 1][j]]) --cdd;
        crs = cr[j + 1] + (int)(!gotu[a[i][j]]);
        res += (long long)cdd * (long long)dw % (long long)MOD *
               (long long)f[n - j - 1][crs] % (long long)MOD;
        res %= MOD;
      } else {
        res += (long long)G[0].sum(a[i][j] - 1) * (long long)fac[n - j - 1] %
               (long long)MOD * (long long)dw % (long long)MOD;
        res %= MOD;
      }
      {
        G[gs(a[i][j])].add(a[i][j], -1);
        got[a[i][j]] = 1;
        G[gs(a[i][j])].add(a[i][j], 1);
      }
    }
  }
  printf("%d\n", res);
  return 0;
}
