func_code_string: #include <bits/stdc++.h>   using namespace std;   int A[2005][2005];   int N, P[2005];   const int MOD = 998244353;   int DP[2005][2005];   bool FreeIn[2005], FreeOut[2005];   int Arb[2][2005], Fact[2005];   int Power[2005];   inline long long norm(long long x) { return x >= MOD ? x - MOD : x; }   void precalcPower() {     Power[0] = 1;     for (int i = 1; i <= N; i++) {       Power[i] = (1LL * Power[i - 1] * DP[0][N]) % MOD;     }   }   void update(int ind, int pos, int val) {     while (pos <= N) {       Arb[ind][pos] += val;       pos += (pos & (-pos));     }   }   int sum(int ind, int pos) {     int ans = 0;     while (pos >= 1) {       ans += Arb[ind][pos];       pos -= (pos & (-pos));     }     return ans;   }   bool check(int N) {     P[1] = 0;     P[0] = 1;     for (int i = 2; i <= N; i++) {       int aux = norm(P[i - 1] + P[i - 2]);       P[i] = (1LL * (i - 1) * aux) % MOD;     }     for (int i = 1; i <= N; i++)       if (DP[0][i] != P[i]) return false;     return true;   }   void precalcDP(int N) {     DP[0][0] = 1;     for (int j = 0; j <= N; j++) {       for (int i = 0; i <= N; i++) {         if (i == 0 && j == 0) continue;         if (i > 0) {           DP[i][j] = (1LL * DP[i - 1][j] * i) % MOD;           if (j > 0) DP[i][j] = norm(DP[i][j] + (1LL * DP[i][j - 1] * j) % MOD);         } else {           if (j >= 2) DP[i][j] = (1LL * DP[i + 1][j - 2] * (j - 1)) % MOD;         }       }     }   }   void Read() {     scanf( %d , &N);     for (int i = 1; i <= N; i++)       for (int j = 1; j <= N; j++) scanf( %d , &A[i][j]);   }   void precalcFact() {     Fact[0] = 1;     for (int i = 1; i <= N; i++) Fact[i] = (1LL * Fact[i - 1] * i) % MOD;   }   void clear() {     for (int i = 1; i <= N; i++) {       FreeIn[i] = FreeOut[i] = true;       Arb[0][i] = Arb[1][i] = 0;     }     for (int i = 1; i <= N; i++) update(1, i, 1);   }   void Solve() {     int ans = 0;     clear();     for (int i = 1; i <= N; i++) {       for (int j = 1; j < A[1][i]; j++) {         if (FreeIn[j]) ans = norm(ans + (1LL * Fact[N - i] * Power[N - 1]) % MOD);       }       FreeIn[A[1][i]] = false;     }     for (int i = 2; i <= N; i++) {       clear();       int x = 0, y = N;       int aux = Power[N - i];       for (int j = 1; j <= N; j++) {         int val = A[i][j];         if (FreeIn[A[i - 1][j]]) {           int freeOut = sum(1, val - 1) - (A[i - 1][j] < A[i][j]);           int busyOut = sum(0, val - 1);           if (y >= 2)             ans = norm(ans +                        (((1LL * DP[x + 1][y - 2] * freeOut) % MOD) * aux) % MOD);           if (y >= 1)             ans =                 norm(ans + (((1LL * DP[x][y - 1] * busyOut) % MOD) * aux) % MOD);         } else {           int freeOut = sum(1, val - 1);           int busyOut = sum(0, val - 1);           if (y > 0)             ans =                 norm(ans + (((1LL * DP[x][y - 1] * freeOut) % MOD) * aux) % MOD);           if (x > 0)             ans =                 norm(ans + (((1LL * DP[x - 1][y] * busyOut) % MOD) * aux) % MOD);         }         if (FreeOut[A[i][j]]) {           if (FreeIn[A[i - 1][j]])             x += 1, y -= 2;           else             y--;         } else {           if (FreeIn[A[i - 1][j]])             y--;           else             x--;         }         if (FreeOut[A[i][j]]) {           update(1, A[i][j], -1);         } else           update(0, A[i][j], -1);         FreeIn[A[i][j]] = false;         if (FreeIn[A[i - 1][j]]) {           update(1, A[i - 1][j], -1);           update(0, A[i - 1][j], 1);         }         FreeOut[A[i - 1][j]] = false;       }     }     printf( %d n , ans);   }   int main() {     Read();     precalcFact();     precalcDP(N);     precalcPower();     Solve();     return 0;   }   