#include <bits/stdc++.h>
using namespace std;
const double PI = 2 * acos(0.0);
const string DIGITS = "0123456789";
const string ALPH = "abcdefghijklmnopqrstuvwxyz";
template <class T>
ostream &operator<<(ostream &out, vector<T> &a) {
  out << "{";
  for (int i = 0; i < int(((int)((a).size()))); ++i)
    out << a[i] << vector<string>{", ", "}"}[i + 1 == ((int)((a).size()))];
  return out;
}
void smain();
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << setprecision(12) << fixed;
  smain();
}
bool check(vector<int> &a) {
  for (int i = 0; i < int(((int)((a).size()))); ++i)
    if (a[i] == i + 1) return 0;
  return 1;
}
long long brute(int n) {
  vector<int> a(n);
  for (int i = 0; i < int(n); ++i) a[i] = i + 1;
  long long ret = 0;
  do {
    ret += check(a);
    if (check(a)) cout << a << endl;
  } while (next_permutation(a.begin(), a.end()));
  return ret;
}
const long long M = 998244353;
long long pw(long long a, long long n) {
  long long ret = 1;
  while (n) {
    if (n & 1) ret = (ret * a) % M;
    a = (a * a) % M;
    n >>= 1;
  }
  return ret;
}
const int N = 2009;
long long fact[N], inv[N];
int lazy[N][N];
void init() {
  fact[0] = inv[0] = 1;
  for (int i = 1; i < N; ++i) {
    fact[i] = fact[i - 1] * i % M;
    inv[i] = pw(fact[i], M - 2);
  }
  for (int i = 0; i < int(N); ++i) fill(lazy[i], lazy[i] + N, -1);
}
inline long long nCr(int n, int k) {
  return fact[n] * inv[k] % M * inv[n - k] % M;
}
long long get_valid(int n, int k = -1) {
  if (k == -1) k = n;
  int ret = 0;
  for (int i = 0; i <= k; ++i) {
    long long cur = nCr(k, i) * fact[n - i] % M;
    if (i & 1) cur = M - cur;
    ret = (ret + cur) % M;
  }
  return ret;
}
struct Fenwik {
  int t[N];
  Fenwik() { fill(t, t + N, 0); }
  inline void upd(int i, int v) {
    for (; i < N; i += i & -i) t[i] += v;
  }
  inline int get(int i) {
    int ret = 0;
    for (; i > 0; i -= i & -i) ret += t[i];
    return ret;
  }
  inline int get(int l, int r) {
    if (!l--) return get(r);
    return get(r) - get(l);
  }
};
long long get_simple_number(const vector<int> &a) {
  set<int> was;
  int n = a.size();
  long long ret = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 1; j < a[i]; ++j) {
      if (!was.count(j)) ret = (ret + fact[n - i - 1]) % M;
    }
    was.insert(a[i]);
  }
  return ret;
}
long long get_dp(int n, int k) {
  if (lazy[n][k] != -1) return lazy[n][k];
  int &ret = lazy[n][k];
  ret = 0;
  if (n == 0 || k == n)
    ret = get_valid(n, k);
  else
    ret = (get_dp(n - 1, k) + get_dp(n, k + 1)) % M;
  return ret;
}
long long get_number(const vector<int> &p, const vector<int> &a) {
  Fenwik pa, aonly;
  int n = a.size();
  for (int i = 0; i < int(n); ++i) pa.upd(i + 1, 1);
  for (int i = 0; i < int(n); ++i) aonly.upd(i + 1, 1);
  long long ret = 0;
  for (int i = 0; i < n; ++i) {
    if (pa.get(p[i], p[i])) pa.upd(p[i], -1);
    int k = pa.get(n);
    int cnt_will = pa.get(a[i] - 1);
    int cnt_wont =
        aonly.get(a[i] - 1) - cnt_will - aonly.get(p[i], p[i]) * (p[i] < a[i]);
    int all_can = pa.get(n);
    long long passed = (get_dp(n - i - 1, all_can) * cnt_wont +
                        get_dp(n - i - 1, all_can - 1) * cnt_will) %
                       M;
    ret = (ret + passed) % M;
    aonly.upd(a[i], -1);
    if (pa.get(a[i], a[i])) pa.upd(a[i], -1);
  }
  return ret;
}
void test_mode() {
  vector<int> p = {1, 2, 3, 4};
  vector<int> a = {2, 1, 4, 3};
  cout << ("get_number(p, a)") << " = " << (get_number(p, a)) << endl;
  ;
  exit(0);
}
void smain() {
  init();
  int n;
  cin >> n;
  vector<int> prev;
  long long ans = 0;
  long long transitions = get_valid(n);
  for (int iter = 0; iter < int(n); ++iter) {
    vector<int> a(n);
    for (int i = 0; i < int(n); ++i) cin >> a[i];
    if (iter == 0) {
      long long cur = get_simple_number(a);
      ans = (ans + cur * pw(transitions, n - iter - 1)) % M;
    } else {
      long long cur = get_number(prev, a);
      ans = (ans + cur * pw(transitions, n - iter - 1)) % M;
    }
    prev = a;
  }
  cout << ans;
}

### Prompt

Generate a CPP solution to the following problem:

Petya collects beautiful matrix.

A matrix of size n × n is beautiful if: 

  * All elements of the matrix are integers between 1 and n; 
  * For every row of the matrix, all elements of this row are different; 
  * For every pair of vertically adjacent elements, these elements are different. 



Today Petya bought a beautiful matrix a of size n × n, and now he wants to determine its rarity.

The rarity of the matrix is its index in the list of beautiful matrices of size n × n, sorted in lexicographical order. Matrix comparison is done row by row. (The index of lexicographically smallest matrix is zero).

Since the number of beautiful matrices may be huge, Petya wants you to calculate the rarity of the matrix a modulo 998 244 353.

Input

The first line contains one integer n (1 ≤ n ≤ 2000) — the number of rows and columns in a.

Each of the next n lines contains n integers a_{i,j} (1 ≤ a_{i,j} ≤ n) — the elements of a.

It is guaranteed that a is a beautiful matrix.

Output

Print one integer — the rarity of matrix a, taken modulo 998 244 353.

Examples

Input


2
2 1
1 2


Output


1


Input


3
1 2 3
2 3 1
3 1 2


Output


1


Input


3
1 2 3
3 1 2
2 3 1


Output


3

Note

There are only 2 beautiful matrices of size 2 × 2:

<image>

There are the first 5 beautiful matrices of size 3 × 3 in lexicographical order:

<image>

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
const double PI = 2 * acos(0.0);
const string DIGITS = "0123456789";
const string ALPH = "abcdefghijklmnopqrstuvwxyz";
template <class T>
ostream &operator<<(ostream &out, vector<T> &a) {
  out << "{";
  for (int i = 0; i < int(((int)((a).size()))); ++i)
    out << a[i] << vector<string>{", ", "}"}[i + 1 == ((int)((a).size()))];
  return out;
}
void smain();
signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << setprecision(12) << fixed;
  smain();
}
bool check(vector<int> &a) {
  for (int i = 0; i < int(((int)((a).size()))); ++i)
    if (a[i] == i + 1) return 0;
  return 1;
}
long long brute(int n) {
  vector<int> a(n);
  for (int i = 0; i < int(n); ++i) a[i] = i + 1;
  long long ret = 0;
  do {
    ret += check(a);
    if (check(a)) cout << a << endl;
  } while (next_permutation(a.begin(), a.end()));
  return ret;
}
const long long M = 998244353;
long long pw(long long a, long long n) {
  long long ret = 1;
  while (n) {
    if (n & 1) ret = (ret * a) % M;
    a = (a * a) % M;
    n >>= 1;
  }
  return ret;
}
const int N = 2009;
long long fact[N], inv[N];
int lazy[N][N];
void init() {
  fact[0] = inv[0] = 1;
  for (int i = 1; i < N; ++i) {
    fact[i] = fact[i - 1] * i % M;
    inv[i] = pw(fact[i], M - 2);
  }
  for (int i = 0; i < int(N); ++i) fill(lazy[i], lazy[i] + N, -1);
}
inline long long nCr(int n, int k) {
  return fact[n] * inv[k] % M * inv[n - k] % M;
}
long long get_valid(int n, int k = -1) {
  if (k == -1) k = n;
  int ret = 0;
  for (int i = 0; i <= k; ++i) {
    long long cur = nCr(k, i) * fact[n - i] % M;
    if (i & 1) cur = M - cur;
    ret = (ret + cur) % M;
  }
  return ret;
}
struct Fenwik {
  int t[N];
  Fenwik() { fill(t, t + N, 0); }
  inline void upd(int i, int v) {
    for (; i < N; i += i & -i) t[i] += v;
  }
  inline int get(int i) {
    int ret = 0;
    for (; i > 0; i -= i & -i) ret += t[i];
    return ret;
  }
  inline int get(int l, int r) {
    if (!l--) return get(r);
    return get(r) - get(l);
  }
};
long long get_simple_number(const vector<int> &a) {
  set<int> was;
  int n = a.size();
  long long ret = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 1; j < a[i]; ++j) {
      if (!was.count(j)) ret = (ret + fact[n - i - 1]) % M;
    }
    was.insert(a[i]);
  }
  return ret;
}
long long get_dp(int n, int k) {
  if (lazy[n][k] != -1) return lazy[n][k];
  int &ret = lazy[n][k];
  ret = 0;
  if (n == 0 || k == n)
    ret = get_valid(n, k);
  else
    ret = (get_dp(n - 1, k) + get_dp(n, k + 1)) % M;
  return ret;
}
long long get_number(const vector<int> &p, const vector<int> &a) {
  Fenwik pa, aonly;
  int n = a.size();
  for (int i = 0; i < int(n); ++i) pa.upd(i + 1, 1);
  for (int i = 0; i < int(n); ++i) aonly.upd(i + 1, 1);
  long long ret = 0;
  for (int i = 0; i < n; ++i) {
    if (pa.get(p[i], p[i])) pa.upd(p[i], -1);
    int k = pa.get(n);
    int cnt_will = pa.get(a[i] - 1);
    int cnt_wont =
        aonly.get(a[i] - 1) - cnt_will - aonly.get(p[i], p[i]) * (p[i] < a[i]);
    int all_can = pa.get(n);
    long long passed = (get_dp(n - i - 1, all_can) * cnt_wont +
                        get_dp(n - i - 1, all_can - 1) * cnt_will) %
                       M;
    ret = (ret + passed) % M;
    aonly.upd(a[i], -1);
    if (pa.get(a[i], a[i])) pa.upd(a[i], -1);
  }
  return ret;
}
void test_mode() {
  vector<int> p = {1, 2, 3, 4};
  vector<int> a = {2, 1, 4, 3};
  cout << ("get_number(p, a)") << " = " << (get_number(p, a)) << endl;
  ;
  exit(0);
}
void smain() {
  init();
  int n;
  cin >> n;
  vector<int> prev;
  long long ans = 0;
  long long transitions = get_valid(n);
  for (int iter = 0; iter < int(n); ++iter) {
    vector<int> a(n);
    for (int i = 0; i < int(n); ++i) cin >> a[i];
    if (iter == 0) {
      long long cur = get_simple_number(a);
      ans = (ans + cur * pw(transitions, n - iter - 1)) % M;
    } else {
      long long cur = get_number(prev, a);
      ans = (ans + cur * pw(transitions, n - iter - 1)) % M;
    }
    prev = a;
  }
  cout << ans;
}

```