Problem: You generate real numbers s1, s2, ..., sn as follows: 

  * s0 = 0; 
  * si = si - 1 + ti, where ti is a real number chosen independently uniformly at random between 0 and 1, inclusive. 



You are given real numbers x1, x2, ..., xn. You are interested in the probability that si ≤ xi is true for all i simultaneously.

It can be shown that this can be represented as <image>, where P and Q are coprime integers, and <image>. Print the value of P·Q - 1 modulo 998244353.

Input

The first line contains integer n (1 ≤ n ≤ 30).

The next n lines contain real numbers x1, x2, ..., xn, given with at most six digits after the decimal point (0 < xi ≤ n).

Output

Print a single integer, the answer to the problem.

Examples

Input

4
1.00
2
3.000000
4.0


Output

1


Input

1
0.50216


Output

342677322


Input

2
0.5
1.0


Output

623902721


Input

6
0.77
1.234567
2.1
1.890
2.9999
3.77


Output

859831967

Note

In the first example, the sought probability is 1 since the sum of i real numbers which don't exceed 1 doesn't exceed i.

In the second example, the probability is x1 itself.

In the third example, the sought probability is 3 / 8.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int N = 35, B = 1000000, revB = 616898040, MOD = 998244353;
int n, m, res, p[N * N], sum[N * N], sz[N * N], f[N * N][N], inv[N], a[N];
inline int get(int x) { return find(p, p + (n * m + 1), x) - p; }
inline void update(int &a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
}
int main() {
  inv[1] = 1;
  for (int i = (2); i <= (N - 1); i++)
    inv[i] = 1LL * (MOD - MOD / i) * inv[MOD % i] % MOD;
  vector<int> frac;
  frac.push_back(0);
  scanf("%d", &n);
  for (int i = (0); i <= (n - 1); i++) {
    double x;
    scanf("%lf", &x);
    a[i] = int(x * B + 0.2);
    frac.push_back(a[i] % B);
  }
  sort((frac).begin(), (frac).end());
  frac.erase(unique((frac).begin(), (frac).end()), frac.end());
  m = frac.size();
  for (int i = (n * m); i >= (0); i--) {
    p[i] = (i / m) * B + frac[i % m];
    if (i < n * m) sz[i] = 1LL * (p[i + 1] - p[i]) * revB % MOD;
  }
  for (int i = (min(get(a[0]), m) - 1); i >= (0); i--)
    sum[i] = sz[i], f[i][1] = 1;
  for (int i = (1); i <= (n - 1); i++) {
    int cut = get(a[i]);
    for (int j = (n * m - 1); j >= (0); j--)
      if (j < cut) {
        for (int k = (max(0, j - m)); k <= (j - 1); k++)
          update(f[j][0], sum[k]);
        if (j >= m)
          for (int k = (0); k <= (n); k++) update(f[j][k], MOD - f[j - m][k]);
        for (int k = (n - 1); k >= (0); k--)
          f[j][k + 1] = 1LL * f[j][k] * inv[k + 1] % MOD;
        f[j][0] = sum[j] = 0;
        for (int k = (n); k >= (0); k--)
          sum[j] = (1LL * sum[j] * sz[j] + f[j][k]) % MOD;
      } else {
        sum[j] = 0;
        memset(f[j], 0, sizeof f[j]);
      }
  }
  for (int i = (0); i <= (n * m - 1); i++) update(res, sum[i]);
  printf("%d\n", res);
  return 0;
}