#include <bits/stdc++.h>
using namespace std;
const long long int K = 998244353;
long long int mu(long long int a, long long int n) {
  if (n == 0) return 1;
  long long int q = mu(a, n / 2);
  if (n % 2 == 0) return q * q % K;
  return q * q % K * a % K;
}
int a[2005][2005];
int n;
long long int gt[2005], rev[2005];
int x[2005], y[2005];
struct BIT {
  int fen[2005];
  void add(int u, int v) {
    for (int i = u; i <= n; i += i & -i) {
      fen[i] += v;
    }
  }
  int getSum(int u) {
    int res = 0;
    for (int i = u; i; i -= i & -i) {
      res += fen[i];
    }
    return res;
  }
} S1, S2;
long long int calc1(int a[2005]) {
  long long int res = 0;
  for (int i = 1; i <= n; i++) S1.add(i, 1);
  for (int i = 1; i <= n; i++) {
    long long int u = S1.getSum(a[i]) - 1;
    if (u < 0) u = 0;
    res = (res + u * gt[n - i] % K) % K;
    S1.add(a[i], -1);
  }
  return res;
}
long long int d[2005][2005];
long long int calc(long long int n, long long int k) {
  if (k < 0) return 0;
  return d[n][k];
}
long long int calc2(int a[2005], int b[2005]) {
  long long int res = 0;
  for (int i = 1; i <= n; i++) {
    S1.fen[i] = 0;
    S2.fen[i] = 0;
    x[i] = 1;
    y[i] = 1;
  }
  for (int i = 1; i <= n; i++) {
    S1.add(i, 1);
    S2.add(i, 1);
  }
  for (int i = 1; i <= n; i++) {
    if (x[a[i]]) {
      x[a[i]] = 0;
      S1.add(a[i], -1);
    }
    long long int k = S1.getSum(n);
    if (a[i] > b[i]) {
      long long int u = S1.getSum(b[i] - 1);
      res = (res + u * calc(n - i, k - 1) % K) % K;
      long long int v = S2.getSum(b[i] - 1) - u;
      if (v < 0) v = 0;
      res = (res + v * calc(n - i, k) % K) % K;
    } else {
      long long int u = S1.getSum(b[i] - 1);
      res = (res + u * calc(n - i, k - 1) % K) % K;
      long long int v = S2.getSum(b[i] - 1) - u;
      if (y[a[i]]) v--;
      if (v < 0) v = 0;
      res = (res + v * calc(n - i, k) % K) % K;
    }
    if (x[b[i]]) {
      x[b[i]] = 0;
      S1.add(b[i], -1);
    }
    S2.add(b[i], -1);
    y[b[i]] = 0;
  }
  return res;
}
long long int calc1_trau(int a[2005]) {
  int b[2005];
  for (int i = 1; i <= n; i++) b[i] = i;
  vector<long long int> v;
  do {
    long long int A = 0;
    for (int i = 1; i <= n; i++) {
      A = (A * 15 + b[i]);
    }
    v.push_back(A);
  } while (next_permutation(b + 1, b + n + 1));
  sort(v.begin(), v.end());
  long long int A = 0;
  for (int i = 1; i <= n; i++) {
    A = (A * 15 + a[i]);
  }
  for (int i = 0; i < v.size(); i++) {
    if (v[i] == A) return i;
  }
  return 0;
}
long long int calc2_trau(int a[2005], int b[2005]) {
  int c[2005];
  for (int i = 1; i <= n; i++) c[i] = i;
  vector<long long int> v;
  do {
    long long int A = 0;
    bool q = 0;
    for (int i = 1; i <= n; i++) {
      if (c[i] == a[i]) q = 1;
    }
    if (q) continue;
    for (int i = 1; i <= n; i++) {
      A = (A * 15 + c[i]);
    }
    v.push_back(A);
  } while (next_permutation(c + 1, c + n + 1));
  sort(v.begin(), v.end());
  long long int A = 0;
  for (int i = 1; i <= n; i++) {
    A = (A * 15 + b[i]);
  }
  for (int i = 0; i < v.size(); i++) {
    if (v[i] == A) return i;
  }
  return 0;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(NULL);
  gt[0] = rev[0] = 1;
  for (int i = 1; i <= 2000; i++) {
    gt[i] = gt[i - 1] * 1ll * i % K;
    rev[i] = mu(gt[i], K - 2);
  }
  for (int i = 0; i <= 2000; i++) d[i][0] = gt[i];
  for (int j = 1; j <= 2000; j++) {
    for (int i = j; i <= 2000; i++) {
      d[i][j] = (d[i][j - 1] - d[i - 1][j - 1] + K) % K;
    }
  }
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) cin >> a[i][j];
  }
  long long int res = 0;
  long long int S = calc(n, n);
  res = calc1(a[1]) * mu(S, n - 1) % K;
  for (int i = 2; i <= n; i++) {
    res = (res + calc2(a[i - 1], a[i]) * mu(S, n - i) % K) % K;
  }
  cout << res << endl;
  return 0;
}
