#include <bits/stdc++.h>
using namespace std;
const int oo = 0x3f3f3f3f;
const long long ooo = 9223372036854775807ll;
const int _cnt = 1000 * 1000 + 7;
const int _p = 1000 * 1000 * 1000 + 7;
const int N = 100005;
const double PI = acos(-1.0);
const double eps = 1e-9;
int o(int x) { return x % _p; }
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
int lcm(int a, int b) { return a / gcd(a, b) * b; }
void file_put() {
  freopen("filename.in", "r", stdin);
  freopen("filename.out", "w", stdout);
}
int inverse(int x, int y) {
  int a = x, b = y, ax = 1, ay = 0, bx = 0, by = 1;
  while (b) {
    int q = a / b, tmp;
    tmp = a - q * b;
    a = b;
    b = tmp;
    tmp = ax - q * bx;
    ax = bx;
    bx = tmp;
    tmp = ay - q * by;
    ay = by;
    by = tmp;
  }
  while (ax < 0) ax += y;
  return ax;
}
template <int MOD>
class num_mod {
  int v;

 public:
  num_mod() : v(0) {}
  num_mod(int v) : v(v) {}
  explicit operator int() const { return v; }
  num_mod& operator+=(num_mod a) {
    v += a.v;
    if (v >= MOD) v -= MOD;
    return *this;
  }
  num_mod& operator-=(num_mod a) {
    v -= a.v;
    if (v < 0) v += MOD;
    return *this;
  }
  num_mod& operator*=(num_mod a) {
    v = v * (int64_t)a.v % MOD;
    return *this;
  }
  num_mod& operator/=(num_mod a) {
    v = v * (int64_t)inverse(a.v, MOD) % MOD;
    return *this;
  }
  num_mod operator+(num_mod x) const { return x += *this; }
  num_mod operator*(num_mod x) const { return x *= *this; }
  num_mod operator-(num_mod x) const {
    num_mod ans = *this;
    return ans -= x;
  }
  num_mod operator/(num_mod x) const {
    num_mod ans = *this;
    return ans /= x;
  }
  num_mod operator-() const { return {MOD - v - MOD * !v}; }
  bool operator==(num_mod x) const { return v == x.v; }
};
template <int DENOM>
class fix_frac {
  int v;

 public:
  fix_frac() : v() {}
  fix_frac(int v) : v(v * DENOM) {}
  fix_frac(int v, int) : v(v) {}
  fix_frac operator-() const { return fix_frac(-v, 0); }
  fix_frac& operator+=(fix_frac x) {
    if (v == INT_MIN) {
    } else if (x.v == INT_MIN)
      v = INT_MIN;
    else
      v += x.v;
    return *this;
  }
  fix_frac& operator-=(fix_frac x) {
    if (v == INT_MIN) return *this;
    v -= x.v;
    return *this;
  }
  fix_frac operator+(fix_frac x) const { return x += *this; }
  fix_frac operator-(fix_frac x) const {
    fix_frac ans = *this;
    return ans -= x;
  }
  template <int MOD>
  explicit operator num_mod<MOD>() const {
    const long long INV_DENOM = inverse(DENOM, MOD);
    int ans = v * INV_DENOM % MOD;
    return {ans + MOD * (ans < 0)};
  }
  bool operator<(fix_frac x) const { return v < x.v; }
  bool operator>(fix_frac x) const { return v > x.v; }
  bool operator<=(fix_frac x) const { return v <= x.v; }
  bool operator>=(fix_frac x) const { return v >= x.v; }
  bool operator==(fix_frac x) const { return v == x.v; }
  bool operator!=(fix_frac x) const { return v != x.v; }
  static fix_frac const MIN;
};
template <int DENOM>
fix_frac<DENOM> const fix_frac<DENOM>::MIN{INT_MIN, 0};
namespace std {
template <int DENOM>
struct numeric_limits<fix_frac<DENOM>> {
  static fix_frac<DENOM> const min() { return fix_frac<DENOM>::MIN; }
};
}  // namespace std
template <class num>
class poly {
 public:
  vector<num> x;
  poly() : x(1) {}
  poly(vector<num> x) : x(move(x)) {}
  poly& operator+=(poly const& b) {
    if (x.size() < b.x.size()) x.resize(b.x.size(), 0);
    for (size_t i = b.x.size(); i-- > 0;) x[i] += b.x[i];
    return *this;
  }
  poly operator+(poly x) const { return x += *this; }
  poly integrate() const {
    poly ans;
    ans.x.resize(x.size() + 1);
    for (size_t i = ans.x.size(); i-- > 1;) ans.x[i] = x[i - 1] / i;
    return ans;
  }
  poly operator*(poly const& b) const {
    vector<num> ans;
    ans.resize(x.size() + b.x.size() - 1);
    for (size_t i = x.size(); i-- > 0;)
      for (size_t j = b.x.size(); j-- > 0;) ans[i + j] += x[i] * b.x[j];
    return poly(move(ans));
  }
  poly& operator*=(poly b) { return *this = *this * b; }
  poly& operator*=(num b) {
    for (num& a : x) a *= b;
    return *this;
  }
  poly operator*(num b) const {
    poly ans = *this;
    return ans *= b;
  }
  poly operator^(poly const& b) const {
    poly ans, base({1});
    for (num v : x) ans += base * v, base *= b;
    return ans;
  }
  poly& operator^=(poly x) { return *this = *this ^ x; }
  poly operator-() const {
    poly ans;
    ans.x.resize(x.size());
    for (size_t i = x.size(); i-- > 0;) ans.x[i] = -x[i];
    return ans;
  }
  num operator()(num a) {
    num base = 1, ans = 0;
    for (num v : x) ans += base * v, base *= a;
    return ans;
  }
};
template <class xnum, class ynum>
class func {
  using polyN = poly<ynum>;
  using funcN = func<xnum, ynum>;
  struct piece {
    polyN p;
    xnum s;
    piece(polyN p, xnum s) : p(p), s(s) {}
  };

 public:
  vector<piece> t;
  func()
      : t{piece{polyN(), std::numeric_limits<xnum>::min()},
          piece{polyN({1}), 0}} {}
  func(vector<piece> t) : t(move(t)) {}
  funcN operator-() const {
    funcN ans(t);
    for (piece& p : ans.t) p.p = -p.p;
    return ans;
  }
  funcN operator+(funcN const& x) const {
    vector<piece> ans, a = t, b = x.t;
    xnum tmp;
    while (!a.empty() && !b.empty()) {
      ans.emplace_back(a.back().p + b.back().p,
                       tmp = max(a.back().s, b.back().s));
      if (a.back().s == tmp) a.pop_back();
      if (b.back().s == tmp) b.pop_back();
    }
    reverse(ans.begin(), ans.end());
    return funcN(move(ans));
  }
  funcN& operator+=(funcN x) { return *this = x + *this; }
  funcN integrate() const {
    vector<piece> ans = t;
    for (piece& p : ans) p.p = p.p.integrate();
    for (size_t i = 1; i < ans.size(); ++i) {
      ynum last_val = ans[i - 1].p((ynum)ans[i].s);
      ynum this_val = ans[i].p((ynum)ans[i].s);
      ans[i].p.x[0] += last_val - this_val;
    }
    return ans;
  }
  funcN& operator>>=(xnum a) {
    polyN p({(ynum)-a, (ynum)1});
    for (piece& pi : t) pi.p ^= p, pi.s += a;
    return *this;
  }
  funcN operator>>(xnum a) const {
    funcN ans = *this;
    return ans >>= a;
  }
  funcN& flatten(xnum a) {
    if (!(t.size() == 1 || t.back().s < a)) {
      while (t.size() >= 2 and (-- --t.end())->s >= a) t.pop_back();
      t.pop_back();
    }
    t.emplace_back(polyN({t.back().p((ynum)a)}), a);
    return *this;
  }
};
int n, ans;
double x;
const int D = 1000000, MOD = 998244353;
int main() {
  func<fix_frac<D>, num_mod<MOD>> f;
  scanf("%d", &n);
  while (n--) {
    scanf("%lf", &x);
    fix_frac<D> xi{(int)round(x * D), 0};
    f = f.integrate(), f += -(f >> 1);
    f.flatten(xi);
  }
  ans = (int)(num_mod<MOD>)f.t.back().p.x[0];
  printf("%d\n", ans);
  return 0;
}
