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;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 30;
const int MAXFRACLEN = 6;
const int MAXLEN = 2 + 1 + MAXFRACLEN;
const int MOD = 998244353;
int pw(int x, int n) {
  int ret = 1;
  while (true) {
    if (n & 1) ret = (long long)ret * x % MOD;
    if ((n >>= 1) == 0) return ret;
    x = (long long)x * x % MOD;
  }
}
int inv(int x) { return pw(x, MOD - 2); }
typedef struct Pol {
  vector<int> coef;
  Pol() {}
  Pol(int cnst) {
    if (cnst != 0) coef.push_back(cnst);
  }
  int eval(int x) {
    int ret = 0;
    for (int i = ((int)(coef).size()) - 1; i >= 0; --i)
      ret = ((long long)ret * x + coef[i]) % MOD;
    return ret;
  }
  void mod(int idx, int by) {
    while (idx >= ((int)(coef).size())) coef.push_back(0);
    coef[idx] = (coef[idx] + by) % MOD;
  }
  void inc(int cnst) { mod(0, cnst); }
  void sub(int cnst) { mod(0, MOD - cnst); }
  void inc(const Pol &a) {
    for (int i = (0); i < (((int)(a.coef).size())); ++i) mod(i, a.coef[i]);
  }
  void sub(const Pol &a) {
    for (int i = (0); i < (((int)(a.coef).size())); ++i)
      mod(i, MOD - a.coef[i]);
  }
  void mlt(int by) {
    for (int i = (0); i < (((int)(coef).size())); ++i)
      coef[i] = (long long)coef[i] * by % MOD;
  }
  Pol integrate() {
    Pol ret(0);
    for (int i = (0); i < (((int)(coef).size())); ++i)
      ret.mod(i + 1, (long long)coef[i] * inv(i + 1) % MOD);
    return ret;
  }
  Pol changevar(int by) {
    Pol ret(0), x(1);
    for (int i = (0); i < (((int)(coef).size())); ++i) {
      for (int j = (0); j < (((int)(x.coef).size())); ++j)
        ret.mod(j, (long long)coef[i] * x.coef[j] % MOD);
      Pol nx(0);
      for (int j = (0); j < (((int)(x.coef).size())); ++j)
        nx.mod(j + 1, x.coef[j]), nx.mod(j, (long long)by * x.coef[j] % MOD);
      x = nx;
    }
    return ret;
  }
} Pol;
typedef struct Seg {
  int lx, rx;
  Pol pol;
  Seg(int lx, int rx, Pol pol) : lx(lx), rx(rx), pol(pol) {}
} Seg;
int n;
char s[MAXN][MAXLEN + 1];
int x[MAXN];
int one;
vector<Seg> segs;
int area() {
  int ret = 0;
  for (int cseg = (0); cseg < (((int)(segs).size())); ++cseg) {
    Pol a = segs[cseg].pol.integrate();
    int cur = 0;
    cur = (cur + a.eval(segs[cseg].rx)) % MOD;
    cur = (cur + MOD - a.eval(segs[cseg].lx)) % MOD;
    ret = (ret + cur) % MOD;
  }
  ret = (long long)ret * inv(one) % MOD;
  return ret;
}
void run() {
  scanf("%d", &n);
  for (int i = (0); i < (n); ++i) scanf("%s", s[i]);
  one = 1;
  for (int j = (0); j < (MAXFRACLEN); ++j) one *= 10;
  for (int i = (0); i < (n); ++i) {
    x[i] = 0;
    bool havesep = false;
    int p = MAXFRACLEN;
    for (int j = 0; s[i][j] != '\0'; ++j)
      if (s[i][j] == '.')
        havesep = true;
      else {
        x[i] = 10 * x[i] + s[i][j] - '0';
        if (havesep) --p;
      }
    for (int j = (0); j < (p); ++j) x[i] *= 10;
  }
  for (int i = n - 2; i >= 0; --i) x[i] = min(x[i], x[i + 1]);
  for (int i = (0); i < (n); ++i)
    x[i] = min(x[i], (i == 0 ? 0 : x[i - 1]) + one);
  segs.clear();
  segs.push_back(Seg(0, x[0], Pol(1)));
  for (int i = (1); i <= (n); ++i) {
    if (i == n) break;
    int cx = 0, lseg = -1, rseg = 0;
    vector<Seg> nsegs;
    while (cx < x[i] && lseg < ((int)(segs).size())) {
      int dx =
          min(min((lseg == -1 ? 0 : segs[lseg].rx) - (cx - one),
                  rseg < ((int)(segs).size()) ? segs[rseg].rx - cx : INT_MAX),
              x[i] - cx);
      Pol pol(0);
      if (lseg == rseg) {
        Pol a = segs[lseg].pol.integrate();
        Pol b = a.changevar(MOD - one);
        pol.inc(a);
        pol.sub(b);
      } else {
        if (lseg >= 0) {
          Pol a = segs[lseg].pol.integrate();
          Pol b = a.changevar(MOD - one);
          pol.inc(a.eval(segs[lseg].rx));
          pol.sub(b);
        }
        if (rseg < ((int)(segs).size())) {
          Pol a = segs[rseg].pol.integrate();
          pol.inc(a);
          pol.sub(a.eval(segs[rseg].lx));
        }
        for (int cseg = (lseg + 1); cseg <= (rseg - 1); ++cseg) {
          Pol a = segs[cseg].pol.integrate();
          pol.inc(a.eval(segs[cseg].rx));
          pol.sub(a.eval(segs[cseg].lx));
        }
      }
      pol.mlt(inv(one));
      nsegs.push_back(Seg(cx, cx + dx, pol));
      cx += dx;
      if (cx - one == (lseg == -1 ? 0 : segs[lseg].rx)) ++lseg;
      if (rseg < ((int)(segs).size()) && cx == segs[rseg].rx) ++rseg;
    }
    segs = nsegs;
  }
  printf("%d\n", area());
}
int main() {
  run();
  return 0;
}