#include <bits/stdc++.h>
using namespace std;
const int N = 2005, M = 998244353;
int read(int x = 0, int f = 1, char c = getchar()) {
  for (; c < '0' || c > '9'; c = getchar())
    if (c == '-') f = -1;
  for (; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - '0';
  return x * f;
}
int n, a[N][N], f[N][N], p[N], fac[N], ans;
struct Tree {
  int t[N], v[N];
  void Add(int x, int w) {
    if (w == -1 && !v[x]) return;
    v[x] ^= 1;
    for (; x <= n; x += x & -x) t[x] += w;
  }
  int Ask(int x, int w = 0) {
    for (; x; x -= x & -x) w += t[x];
    return w;
  }
  void Init() {
    for (int i = 1; i <= n; ++i) t[i] = i & -i, v[i] = 1;
  }
} t1, t2;
int main() {
  n = read();
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= n; ++j) a[i][j] = read();
  f[0][0] = 1;
  f[1][1] = 0;
  f[2][2] = 1;
  for (int i = 3; i <= n; ++i)
    f[i][i] = 1ll * (i - 1) * (f[i - 1][i - 1] + f[i - 2][i - 2]) % M;
  for (int i = 1; i <= n; ++i)
    for (int j = i - 1; j >= 0; --j)
      if ((f[i][j] = f[i][j + 1] + f[i - 1][j]) >= M) f[i][j] -= M;
  fac[0] = p[0] = 1;
  for (int i = 1; i <= n; ++i) {
    fac[i] = 1ll * fac[i - 1] * i % M;
    p[i] = 1ll * p[i - 1] * f[n][n] % M;
  }
  t1.Init();
  for (int j = 1; j <= n; ++j)
    t1.Add(a[1][j], -1), ans = (ans + 1ll * t1.Ask(a[1][j]) * fac[n - j]) % M;
  ans = 1ll * ans * p[n - 1] % M;
  for (int i = 2; i <= n; ++i) {
    int sum = 0;
    t1.Init();
    t2.Init();
    for (int j = 1; j <= n; ++j) {
      int tot, cnt, tmp;
      t1.Add(a[i][j], -1);
      tot = t1.Ask(a[i][j]);
      if (a[i - 1][j] < a[i][j] && t1.v[a[i - 1][j]]) tot--;
      t2.Add(a[i - 1][j], -1);
      tmp = t2.Ask(n);
      cnt = t2.Ask(a[i][j] - 1);
      sum = (sum + 1ll * cnt * f[n - j][tmp - 1] +
             1ll * (tot - cnt) * f[n - j][tmp]) %
            M;
      t2.Add(a[i][j], -1);
    }
    ans = (ans + 1ll * sum * p[n - i]) % M;
  }
  printf("%d\n", ans);
  return 0;
}
