#include <bits/stdc++.h>

#define SQ(a) (a)*(a)

#define F0R(i, a) for(int i = 0; i < (a); i++)
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define R0F(i, a) for(int i = (a) - 1; i >= 0; i--)
#define ROF(i, a, b) for(int i = (b) - 1; i >= (a); i--)

#define ran() (rand() & 0x7FFF)
#define rand31() ((ran() << 16) | (ran() << 1) | (ran() & 1))
#define rand32() ((ran() << 17) | (ran() << 2) | (ran() & 3))
#define rand63() (((ll)ran() << 48) | ((ll)ran() << 33) | ((ll)ran() << 18) | ((ll)ran() << 3) | ((ll)ran() & 7))
#define rand64() (((ll)ran() << 49) | ((ll)ran() << 34) | ((ll)ran() << 19) | ((ll)ran() << 4) | ((ll)ran() & 15))

#define F first
#define S second
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define UB upper_bound
#define LB lower_bound
#define X real()
#define Y imag()
#define R real()
#define I image()
#define PI acos(-1)
#define MAXN 30

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef complex<ld> point;
typedef complex<ld> cld;

namespace NTT {

const int MAX_DEG = 20, EXP_MULT = 119ULL, EXP = 23;
ull NTTMod = (EXP_MULT << EXP) + 1, NTTBuild[1 << MAX_DEG][2], rt[(1 << MAX_DEG) + 1];

ull modPow(ull a, ull p) {
    if(!p) return 1;
    if(p & 1) return a * modPow(a, p ^ 1) % NTTMod;
    ull sqrt = modPow(a, p >> 1);
    return SQ(sqrt) % NTTMod;
}

ull invMod(ull a) {
    return modPow(a, NTTMod - 2);
}

ull findCyclic() {
    vi multFactors;
    ull temp = EXP_MULT;
    for(int i = 2; i * i <= temp; i += 2) {
        if(temp % i == 0) multFactors.PB(i);
        while(temp % i == 0) temp /= i;
        if(i == 2) i--;
    }
    if(temp > 1) multFactors.PB(temp);
    FOR(i, 2, NTTMod) {
        bool works = 1;
        if(modPow(i, NTTMod >> 1) == 1) works = 0;
        for(const int factor : multFactors) if(modPow(i, NTTMod / factor) == 1) works = 0;
        if(works) return i;
    }
}

void buildRT() {
    if(rt[0] == 1) return;
    rt[0] = 1;
    rt[1] = modPow(findCyclic(), EXP_MULT << (EXP - MAX_DEG));
    FOR(i, 2, (1 << MAX_DEG) + 1) rt[i] = rt[i - 1] * rt[1] % NTTMod;
}

void ntt(int neededDeg, ull* vals, int len) {
    R0F(i, neededDeg + 1) {
        int arr = i & 1, narr = arr ^ 1, lli = 1 << i, llil = lli << 1, llndim1 = 1 << (neededDeg - i - 1), rtp = lli << (MAX_DEG - neededDeg);
        if(i == neededDeg) {
            F0R(j, len) NTTBuild[j][arr] = vals[j];
            FOR(j, len, lli) NTTBuild[j][arr] = 0;
        } else F0R(j, lli) {
            int x = j, y = 0, z = j, w = j + lli;
            F0R(k, llndim1) {
                NTTBuild[x][arr] = (NTTBuild[z][narr] + NTTBuild[w][narr] * rt[y]) % NTTMod;
                x += lli, y += rtp, z += llil, w += llil;
            }
            z = j, w = j + lli;
            F0R(k, llndim1) {
                NTTBuild[x][arr] = (NTTBuild[z][narr] + NTTBuild[w][narr] * rt[y]) % NTTMod;
                x += lli, y += rtp, z += llil, w += llil;
            }
        }
    }
}

void invntt(int pdeg, ull* p, int len) {
    reverse(rt, rt + (1 << MAX_DEG) + 1);
    R0F(i, pdeg + 1) {
        int arr = i & 1, narr = arr ^ 1, lli = 1 << i, llil = lli << 1, llpdim1 = 1 << (pdeg - i - 1), rtp = lli << (MAX_DEG - pdeg);
        R0F(j, lli) {
            if(i == pdeg) NTTBuild[j][arr] = p[j];
            else {
                int x = j, y = 0, z = j, w = j + lli;
                F0R(k, llpdim1) {
                    NTTBuild[x][arr] = (NTTBuild[z][narr] + NTTBuild[w][narr] * rt[y]) % NTTMod;
                    x += lli, y += rtp, z += llil, w += llil;
                }
                z = j, w = j + lli;
                F0R(k, llpdim1) {
                    NTTBuild[x][arr] = (NTTBuild[z][narr] + NTTBuild[w][narr] * rt[y]) % NTTMod;
                    x += lli, y += rtp, z += llil, w += llil;
                }
            }
        }
    }
    reverse(rt, rt + (1 << MAX_DEG) + 1);
    ull u = invMod(len);
    F0R(i, len) NTTBuild[i][0] *= u, NTTBuild[i][0] %= NTTMod;
}

};

using namespace NTT;

ull tempPVPoly[1 << MAX_DEG];

struct Polynomial {

    int deg;
    ull *coefficients;

    Polynomial(int d = 0) {
        deg = d;
        coefficients = new ull[deg + 1];
        memset(coefficients, 0, (deg + 1) * sizeof(ull));
        buildRT();
    }

    Polynomial operator ()(Polynomial p) {
        Polynomial curr;
        curr[0] = 1;
        Polynomial res;
        F0R(i, deg + 1) {
            res += curr * coefficients[i];
            curr *= p;
        }
        return res;
    }

    ull& operator [](int idx) { return coefficients[idx]; }

    Polynomial operator +(ull a) {
        Polynomial p(deg);
        F0R(i, deg + 1) p[i] = coefficients[i];
        p[0] += a;
        p[0] %= NTTMod;
        return p;
    }

    Polynomial operator -(ull a) {
        Polynomial p(deg);
        F0R(i, deg + 1) p[i] = coefficients[i];
        p[0] += NTTMod - a;
        p[0] %= NTTMod;
        return p;
    }

    Polynomial operator *(ull mult) {
        Polynomial p(deg);
        F0R(i, deg + 1) p[i] = coefficients[i] * mult % NTTMod;
        return p;
    }

    Polynomial operator /(ull div) { return *this * invMod(div); }

    Polynomial operator +(Polynomial b) {
        Polynomial res(max(deg, b.deg));
        F0R(i, max(deg, b.deg) + 1) res[i] = (((i > deg) ? 0 : coefficients[i]) + ((i > b.deg) ? 0 : b[i])) % NTTMod;
        return res;
    }

    Polynomial operator -(Polynomial p) { return *this + (p * (NTTMod - 1)); }

    Polynomial operator *(Polynomial b) {
        int neededDeg = 32 - __builtin_clz(deg + b.deg);
        ntt(neededDeg, coefficients, deg + 1);
        F0R(i, (1 << neededDeg)) tempPVPoly[i] = NTTBuild[i][0];
        ntt(neededDeg, b.coefficients, b.deg + 1);
        F0R(i, (1 << neededDeg)) tempPVPoly[i] = tempPVPoly[i] * NTTBuild[i][0] % NTTMod;
        invntt(neededDeg, tempPVPoly, 1 << neededDeg);
        Polynomial res(deg + b.deg);
        F0R(i, res.deg + 1) res[i] = NTTBuild[i][0];
        return res;
    }

    void operator +=(ull a) { coefficients[0] += a, coefficients[0] %= NTTMod; }

    void operator -=(ull a) { *this += NTTMod - a; }

    void operator *=(ull mult) { F0R(i, deg + 1) coefficients[i] *= mult, coefficients[i] %= NTTMod; }

    void operator /=(ull div) { *this *= invMod(div); }

    void operator +=(Polynomial b) { *this = *this + b; }

    void operator -=(Polynomial p) { *this = *this - p; }

    void operator *=(Polynomial b) { *this = *this * b; }

};

int n;
ull x[MAXN];
ull modX[MAXN];
vector<pair<Polynomial, pair<pair<ull, ull>, pair<ull, ull>>>> func;

Polynomial indefInt(Polynomial f) {
    Polynomial res(f.deg + 1);
    FOR(i, 1, res.deg + 1) res[i] = f[i - 1] * invMod(i) % NTTMod;
    return res;
}

Polynomial defInt(Polynomial f, Polynomial lo, Polynomial hi) {
    Polynomial F = indefInt(f);
    return F(hi) - F(lo);
}

Polynomial makeCopy(Polynomial p) {
    Polynomial res(p.deg);
    F0R(i, res.deg + 1) res[i] = p[i];
    return res;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    F0R(i, n) {
        string s;
        cin >> s;
        int numDecimalPlaces = 0;
        R0F(j, s.size()) if(s[j] == '.') numDecimalPlaces = s.size() - j - 1;
        ull base = modPow(10, 6 - numDecimalPlaces);
        R0F(j, s.size()) if(s[j] != '.') {
            x[i] += base * (s[j] - '0');
            base *= 10;
        }
    }
    x[0] = min(1000000ULL, x[0]);
    FOR(i, 1, n) x[i] = min(x[i], x[i - 1] + 1000000ULL);
    ull invMillion = invMod(1000000ULL);
    F0R(i, n) modX[i] = x[i] * invMillion % NTTMod;
    func.PB(MP(Polynomial(), MP(MP(0, 0), MP(x[0], modX[0]))));
    func[0].F[0] = 1;
    Polynomial xPoly(1);
    xPoly[1] = 1;
    F0R(i, n - 1) {
        vector<Polynomial> v2;
        vector<tuple<pair<ull, ull>, bool, int>> v;
        F0R(j, func.size()) {
            pair<double, ull> lo = func[j].S.F;
            pair<double, ull> hi = func[j].S.S;
            Polynomial loPoly;
            Polynomial hiPoly;
            loPoly[0] = lo.S;
            hiPoly[0] = hi.S;
            pair<double, ull> xVal = MP(x[i + 1], modX[i + 1]);
            pair<double, ull> loP1 = MP(lo.F + 1000000ULL, (lo.S + 1) % NTTMod);
            pair<double, ull> hiP1 = MP(hi.F + 1000000ULL, (hi.S + 1) % NTTMod);
            if(xVal.F > lo.F) {
                v2.PB(defInt(func[j].F, loPoly, xPoly));
                v.PB(MT(lo, 1, v2.size() - 1));
                v.PB(MT(min(hi, xVal), 0, v2.size() - 1));
            }
            if(hi.F < lo.F + 1000000ULL && xVal.F > hi.F) {
                v2.PB(defInt(func[j].F, loPoly, hiPoly));
                v.PB(MT(hi, 1, v2.size() - 1));
                v.PB(MT(min(loP1, xVal), 0, v2.size() - 1));
            }
            if(lo.F + 1000000ULL < xVal.F) {
                v2.PB(defInt(func[j].F, xPoly + (NTTMod - 1), hiPoly));
                v.PB(MT(loP1, 1, v2.size() - 1));
                v.PB(MT(min(hiP1, xVal), 0, v2.size() - 1));
            }
        }
        func.clear();
        sort(v.begin(), v.end());
        pair<ull, ull> last = MP(0, 0);
        Polynomial curr;
        for(const tuple<pair<ull, ull>, bool, int> t : v) {
            if(get<0>(t) > last) func.PB(MP(makeCopy(curr), MP(last, get<0>(t))));
            if(get<1>(t)) curr += v2[get<2>(t)];
            else curr -= v2[get<2>(t)];
            last = get<0>(t);
        }
    }
    Polynomial res;
    F0R(i, func.size()) {
        Polynomial lo, hi;
        lo[0] = func[i].S.F.S;
        hi[0] = func[i].S.S.S;
        res += defInt(func[i].F, lo, hi);
    }
    cout << res[0] << endl;
    return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdio.h>
#include<vector>
#include<map>
#include<set>
using namespace std;
const double eps=1e-9;
const int mod=998244353;
double x[33],xp[33];
struct pp
{
    double vl;
    int zz;
    bool operator <(const pp &temp)const
    {
        return vl<temp.vl;
    }
};
pp sg[33][33*33*2];
pp now;
int cnt_sg[33];
int n,zi,mu,y[33],coef[33][33*33][33],nc[33],c[33][33],inv[33];
int power(int a,int n)
{
    if(n==0)
       return 1;
    int ret=power(a,n/2);
    ret=1LL*ret*ret%mod;
    if(n%2)
       ret=1LL*ret*a%mod;
    return ret;
}
int main()
{
    scanf("%d",&n);
    int i,j,s,p,q;
    x[0]=xp[0]=0;
    for(i=0;i<=n;i++)
      for(j=0;j<=i;j++)
      {
          if(j==0||j==i)
             c[i][j]=1;
          else
             c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
      }
    for(i=0;i<n;i++)
    {
       scanf("%lf",&x[i]);
       x[i]=min(i+1.,x[i]);
       if(i)
         x[i]=min(xp[i-1]+1,x[i]);
       xp[i]=x[i];
       zi=0;
       mu=1;
       int zz=0;
       while(true)
       {
          zi=(int)(x[i]+eps);
          zz=1LL*zz*10+zi;
       //   printf("zz=%d\n",zz);
          x[i]=x[i]-zi;
         // printf("x[i]=%.20f\n",x[i]);
         // system("pause");
             if(fabs(x[i])<1e-7)
             break;
          x[i]*=10;
          mu*=10;
       }
       zi=zz;
       y[i]=1LL*zi*power(mu,mod-2)%mod;
      //printf("y[i]=%d,zi=%d,mu=%d\n",y[i],zi,mu);
    }
    memset(cnt_sg,0,sizeof(cnt_sg));
    sg[0][cnt_sg[0]].vl=sg[0][cnt_sg[0]].zz=0;
    cnt_sg[0]++;
    sg[0][cnt_sg[0]].vl=xp[0];
    sg[0][cnt_sg[0]++].zz=y[0];
    memset(coef,0,sizeof(coef));
    coef[0][0][0]=1;
    for(i=0;i<=n;i++)
       inv[i]=power(i,mod-2);
    for(i=0;i+1<n;i++)
    {
        cnt_sg[i+1]=0;
        for(j=0;j<cnt_sg[i];j++)
          for(s=-(int)(sg[i][j].vl+1-eps);;s++)
          {
               now.vl=sg[i][j].vl+s;
               if(now.vl<0)
               {
                    now.vl=0;
                    now.zz=0;
               }
               else
               {
                  now.zz=(sg[i][j].zz+s)%mod;
                  if(now.zz<0)
                     now.zz+=mod;
               }
               if(now.vl>=xp[i+1])
                   break;
               sg[i+1][cnt_sg[i+1]++]=now;
        }
        for(s=-(int)(xp[i+1]+1-eps);s<=0;s++)
        {
            now.vl=xp[i+1]+s;
            if(now.vl<0)
            {
                now.vl=0;
                now.zz=0;
            }
            else
            {
                now.zz=(y[i+1]+s)%mod;
                if(now.zz<0)
                  now.zz+=mod;
            }
            sg[i+1][cnt_sg[i+1]++]=now;
        }
		sort(sg[i+1],sg[i+1]+cnt_sg[i+1]);
        int nn=0;
        for(j=0;j<cnt_sg[i+1];j++)
        {
            if(nn==0||sg[i+1][nn-1].zz!=sg[i+1][j].zz)
               sg[i+1][nn++]=sg[i+1][j];
        }
        cnt_sg[i+1]=nn;
        s=0;
        int us=0;
        for(j=0;j+1<cnt_sg[i+1];j++)
        {
            while(us<cnt_sg[i]&&sg[i][us].vl<=sg[i+1][j].vl-1+eps)
               us++;
            s=us;
           int bz;
            while(s<cnt_sg[i]&&sg[i][s].vl<=sg[i+1][j].vl+eps)
            {
                double ll,rr;
                int lz,rz;
                if(s==us)
                {
                    for(p=0;p<=i&&s;p++)
                    {
                        int vc=1LL*coef[i][s-1][p]*inv[p+1]%mod;
                        for(q=0;q<=p+1;q++)
                        {
                            int bc=1LL*vc*c[p+1][q]%mod;
                            if((p+1-q)%2)
                               coef[i+1][j][q]=(coef[i+1][j][q]+bc)%mod;
                            else
                               coef[i+1][j][q]=(coef[i+1][j][q]-bc+mod)%mod;
                        }
                    }
                }
                bz=0;
                for(p=i;p>=0&&s;p--)
                	bz=(1LL*bz*sg[i][s].zz+1LL*coef[i][s-1][p]*inv[p+1])%mod;
				coef[i+1][j][0]=(coef[i+1][j][0]+1LL*bz*sg[i][s].zz)%mod;
				if(s>us)
				{
					bz=0;
					for(p=i;p>=0;p--)
						bz=(1LL*bz*sg[i][s-1].zz+1LL*coef[i][s-1][p]*inv[p+1])%mod;
					coef[i+1][j][0]=(coef[i+1][j][0]-1LL*bz*sg[i][s-1].zz%mod+mod)%mod;
				}
                s++;
            }
            if(s<cnt_sg[i])
            {
            	s--;
			    bz=0;
			    for(p=i;p>=0;p--)
		    	   bz=(1LL*bz*sg[i][s].zz+1LL*coef[i][s][p]*inv[p+1])%mod;
			    coef[i+1][j][0]=(coef[i+1][j][0]-1LL*bz*sg[i][s].zz%mod+mod)%mod;
                for(p=0;p<=i;p++)
                    coef[i+1][j][p+1]=(coef[i+1][j][p+1]+1LL*coef[i][s][p]*power(p+1,mod-2))%mod;
            }
        }
    }
    int ans=0;
    for(i=0;i<cnt_sg[n-1]-1;i++)
    {
        int bz=0,lz=sg[n-1][i].zz,rz=sg[n-1][i+1].zz;
        for(j=n-1;j>=0;j--)
            bz=(1LL*bz*rz+1LL*coef[n-1][i][j]*inv[j+1])%mod;
        ans=(ans+1LL*bz*rz)%mod;
        bz=0;
        for(j=n-1;j>=0;j--)
            bz=(1LL*bz*lz+1LL*coef[n-1][i][j]*inv[j+1])%mod;
        ans=(ans-1LL*bz*lz%mod+mod)%mod;
    }
    printf("%d\n",ans);
    return 0;
}


//#define LOCAL

#ifdef LOCAL
  #define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <set>

#ifdef DBG1
    #define dbg(...) fprintf(stderr, __VA_ARGS__)
#else
    #define dbg(...)
#endif

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;

const int P = 998244353;

int mod(ll a) {
  a %= P;
  if (a < 0) {
    a += P;
  }
  return a;
}

int sum(int a, int b) {
  if ((a += b) >= P) {
    a -= P;
  }
  return a;
}

int diff(int a, int b) {
  if ((a -= b) < 0) {
    a += P;
  }
  return a;
}

int prod(int a, int b) {
  return ll(a) * b % P;
}

int power(int a, int n) {
  int b = 1;
  while (n) {
    if (n & 1) {
      b = prod(a, b);
    }
    a = prod(a, a);
    n /= 2;
  }
  return b;
}

int inv(int a) {
  return power(a, P - 2);
}

int divide(int a, int b) {
  assert(b != 0);
  return prod(a, inv(b));
}

ll gcd(ll a, ll b) {
  if (b) return gcd(b, a % b);
  return a;
}

struct Fraction {
  ll a, b;

  Fraction(ll _a = 0, ll  _b = 1) {
    ll d = gcd(_a, _b);
    a = _a / d;
    b = _b / d;
    if (b < 0) {
      a *= -1;
      b *= -1;
    }
  }

  Fraction operator - () const {
    return Fraction(-a, b);
  }

  Fraction operator + (const Fraction & f) const {
    return Fraction(a * f.b + f.a * b, b * f.b);
  }

  Fraction operator - (const Fraction & f) const {
    return Fraction(a * f.b - f.a * b, b * f.b);
  }

  int getModValue() const {
    return divide(mod(a), mod(b));
  }

  bool operator < (const Fraction & f) const {
    return a * f.b < f.a * b;
  }

  bool operator <= (const Fraction & f) const {
    return !(f < *this);
  }

  bool operator > (const Fraction & f) const {
    return f < *this;
  }

  bool operator >= (const Fraction & f) const {
    return !(*this < f);
  }

  bool operator == (const Fraction & f) const {
    return a == f.a && b == f.b;
  }

  void dbgPrint() const {
    dbg("%lld/%lld", a, b);
  }
};

Fraction readDecimal() {
  static char s[20];
  assert(scanf("%s", s) == 1);
  int len = (int)strlen(s);
  char *dot = strchr(s, '.');
  int frac_len = 0;
  if (dot) {
    memmove(dot, dot + 1, s + len - dot);
    frac_len = s + len - dot - 1;
  }
  int a = atoi(s);
  int b = 1;
  for (int i = 0; i < frac_len; ++i) {
    b *= 10;
  }
  dbg("%s: %d/%d\n", __func__, a, b);
  return Fraction(a, b);
}

struct Polynom {
  vector <int> coefs;

  Polynom(int a = 0) : coefs(1, a) {}
  Polynom(const vector<int>&coefs) : coefs(coefs) {}

  Polynom& operator += (const Polynom & p) {
    while (coefs.size() < p.coefs.size()) {
      coefs.push_back(0);
    }
    for (int i = 0; i < int(p.coefs.size()); ++i) {
      coefs[i] = sum(coefs[i], p.coefs[i]);
    }
    return *this;
  }

  Polynom& operator -= (const Polynom & p) {
    while (coefs.size() < p.coefs.size()) {
      coefs.push_back(0);
    }
    for (int i = 0; i < int(p.coefs.size()); ++i) {
      coefs[i] = diff(coefs[i], p.coefs[i]);
    }
    return *this;
  }

  Polynom operator * (const Polynom & p2) const {
    const Polynom & p1 = *this;
    Polynom p;
    p.coefs.resize(p1.coefs.size() + p2.coefs.size() - 1);
    for (int i = 0; i < int(p1.coefs.size()); ++i) {
      for (int j = 0; j < int(p2.coefs.size()); ++j) {
        p.coefs[i + j] = sum(p.coefs[i + j], prod(p1.coefs[i], p2.coefs[j]));
      }
    }
    while (p.coefs.size() > 1 && p.coefs.back() == 0) {
      p.coefs.pop_back();
    }
    return p;
  }

  Polynom& operator *= (const Polynom & p) {
    return *this = *this * p;
  }

  int getValue(const Fraction &x) const {
    //dbg("getValue("); x.dbgPrint(); dbg(")\n");
    int xx = x.getModValue();
    int val = 0;
    for (int i = int(coefs.size()) - 1; i >= 0; --i) {
      val = prod(val, xx);
      val = sum(val, coefs[i]);
    }
    return val;
  }

  Polynom substitute_x_minus_y(const Fraction &y) const {
    Polynom p(0);
    Polynom tmp({(-y).getModValue(), 1});
    for (int i = int(coefs.size()) - 1; i >= 0; --i) {
      p *= tmp;
      p += coefs[i];
    }
    return p;
  }

  Polynom getPrimitive() const {
    Polynom p;
    p.coefs.resize(coefs.size() + 1);
    p.coefs[0] = 0;
    for (int i = 0; i < int(coefs.size()); ++i) {
      p.coefs[i + 1] = divide(coefs[i], i + 1);
    }
    dbgPrint();
    p.dbgPrint();
    return p;
  }

  void dbgPrint() const {
    for (int i = 0; i < int(coefs.size()); ++i) {
      dbg("%d*x^%d + ", coefs[i], i);
    }
    dbg("\n");
  }
};

struct Function {
  vector<Fraction> borders;
  vector<Polynom> parts;

  Function(const Fraction & left, const Fraction & right, const Polynom & p) {
    borders.push_back(left);
    borders.push_back(right);
    parts.push_back(p);
  }

  Function(const vector <Fraction> & borders, const vector<Polynom> & parts) : borders(borders), parts(parts) {}

  Polynom getIntegral(const Fraction & len, const Fraction & R1, const Fraction & R2) const {
    assert(R1 < R2);
    Fraction L1 = R1 - len;
    Fraction L2 = R2 - len;
    L1.dbgPrint(); dbg(" "); L2.dbgPrint(); dbg(" "); R1.dbgPrint(); dbg(" "); R2.dbgPrint(); dbg("\n");
    Polynom res({0});
    for (int i = 0; i < int(parts.size()); ++i) {
      if (R2 <= borders[i]) { break; }
      if (L1 >= borders[i + 1]) { continue; }
      borders[i].dbgPrint(); dbg(" "); borders[i + 1].dbgPrint(); dbg("\n");
      //assert(max(L2, borders[i]) <= min(R1, borders[i + 1]));
      Polynom f = parts[i].getPrimitive();
      if (max(L1, borders[i]) == max(L2, borders[i])) {
        dbg("res -= f("); max(L2, borders[i]).dbgPrint(); dbg(")\n");
        res -= f.getValue(max(L2, borders[i]));
        res.dbgPrint();
      } else {
        dbg("res -= f(x-1)\n");
        f.substitute_x_minus_y(len).dbgPrint();
        res -= f.substitute_x_minus_y(len);
        res.dbgPrint();
      }
      if (min(R1, borders[i + 1]) == min(R2, borders[i + 1])) {
        dbg("res += f("); min(R1, borders[i + 1]).dbgPrint(); dbg(")\n");
        res += f.getValue(min(R1, borders[i + 1]));
        res.dbgPrint();
      } else {
        dbg("res += f(x)\n");
        res += f;
        res.dbgPrint();
      }
    }
    dbg("%s returns ", __func__); res.dbgPrint();
    return res;
  }

  void truncate(Fraction x) {
    dbg("%s\n", __func__);
    while (borders[int(borders.size()) - 2] >= x) {
      borders.pop_back();
      parts.pop_back();
    }
    assert(x <= borders.back());
    assert(borders[int(borders.size()) - 2] < x);
    borders.back() = x;
  }

  void extend(Fraction x) {
    assert(borders.back() <= x);
    if (borders.back() < x) {
      parts.push_back(Polynom(parts.back().getValue(borders.back())));
      borders.push_back(x);
    }
  }

  void dbgPrint() {
    for (int i = 0; i < int(parts.size()); ++i) {
      dbg("["); borders[i].dbgPrint();
      dbg(", "); borders[i + 1].dbgPrint();
      dbg("] => ");
      parts[i].dbgPrint();
      assert(borders[i] < borders[i + 1]);
    }
  }
};

Function addRandomVar(const Function & f) {
  vector <Fraction> borders = f.borders;
  for (int i = 0; i < int(f.borders.size()); ++i) {
    borders.push_back(f.borders[i] + 1);
  }
  sort(borders.begin(), borders.end());
  borders.erase(unique(borders.begin(), borders.end()), borders.end());

  vector<Polynom> parts;
  parts.reserve((int)borders.size() - 1);
  for (int i = 1; i < int(borders.size()); ++i) {
    Fraction right = borders[i];
    Fraction left = borders[i - 1];
    dbg("left = "); left.dbgPrint();
    dbg(" right = "); right.dbgPrint(); dbg("\n");
    Polynom curP = f.getIntegral(1, left, right);
    parts.push_back(curP);
  }

  return Function(borders, parts);
}

bool solve() {
  int n;
  if (scanf("%d", &n) != 1) { return false; }

  Fraction x0 = readDecimal();
  Function f(0, x0, Polynom({0, 1}));
  for (int i = 1; i < n; ++i) {
    dbg("ANS %d\n", f.parts.back().getValue(f.borders.back()));

    Fraction x = readDecimal();
    f.extend(i + 1);
    f = addRandomVar(f);
    f.dbgPrint();
    f.truncate(x);

    f.dbgPrint();
  }
  printf("%d\n", f.parts.back().getValue(f.borders.back()));
  return true;
}

int main() {
  while (solve());
  return 0;
}


/*
* C++11 code template for contests.
* @author: Andrey Kalendarov
* @e-mail: andreykalendarov@gmail.com
*/

/*______ DEFINES _______*/

#define _SCL_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
//#define ANDREIKKAA_ALLOCATOR
//#define ANDREIKKAA_UNSAFE_VECTOR

#ifdef ANDREIKKAA_UNSAFE_VECTOR
#define vec vector
#endif // ANDREIKKAA_UNSAFE_VECTOR

typedef long long ll;
typedef long double ld;

const int MEMORY_LIMIT_MB = 250;
const int TIME_LIMIT_S = 1;

const char input_filename[] =
#ifdef ANDREIKKAA
"input.txt"
#else
""
#endif
;
const char output_filename[] =
#ifdef ANDREIKKAA
""
#else
""
#endif
;

/* ______ INCLUDES ______ */

#include <cassert>
#include <cctype>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <cmath>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cstdint>
#include <ctgmath>

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <valarray>
#include <vector>

#include <array>
#include <forward_list>
#include <initializer_list>
#include <regex>
#include <unordered_map>
#include <unordered_set>
using namespace std;

/*_______ TYPES ________*/

template<typename T, typename U>
ostream &operator<<(ostream &out, const pair<T, U> &p)
{
	out << p.first << ' ' << p.second;
	return out;
}

template<typename T, typename U>
istream &operator>>(istream &in, pair<T, U> &p)
{
	in >> p.first >> p.second;
	return in;
}

#ifndef ANDREIKKAA_UNSAFE_VECTOR
template<typename T>
class vec : public vector<T>
{
public:
	using vector<T>::vector;
	inline const T operator[](size_t x) const
	{
		return this->at(x);
	}
	inline T& operator[](size_t x)
	{
		return this->at(x);
	}
};

template<>
class vec<bool> : public vector<bool>
{
	using vector<bool>::vector;
	inline const_reference operator[](size_t x) const
	{
		return this->at(x);
	}
	inline reference operator[](size_t x)
	{
		return this->at(x);
	}
};

template<typename T>
inline ostream &operator<<(ostream &out, const vec<T> &v)
{
	if (v.empty())
		return out;
	out << v.front();
	for (auto it = ++v.begin(); it != v.end(); ++it)
		out << ' ' << *it;
	return out;
}

template<typename T>
inline istream &operator>>(istream &in, vec<T> &v)
{
	for (auto &i : v)
		in >> i;
	return in;
}
#endif // !ANDREIKKAA_UNSAFE_VECTOR

template<typename T>
inline ostream &operator<<(ostream &out, const vector<T> &v)
{
	if (v.empty())
		return out;
	out << v.front();
	for (auto it = ++v.begin(); it != v.end(); ++it)
		out << ' ' << *it;
	return out;
}

template<typename T>
inline istream &operator>>(istream &in, vector<T> &v)
{
	for (auto &i : v)
		in >> i;
	return in;
}

/* _____ ALLOCATION _____ */

#ifdef ANDREIKKAA_ALLOCATOR
char alloc_memory[MEMORY_LIMIT_MB * 1000 * 1000];
size_t alloc_pointer = 0;
inline void* operator new(size_t x)
{
	alloc_pointer += x;
return alloc_memory + alloc_pointer - x;
}
inline void operator delete(void* x)
{

}
#endif

/* _______ INPUT _________*/

class Reader
{
public:
	inline Reader(const string &filename)
	{
		cin.tie(nullptr);//, ios_base::sync_with_stdio(false);
		if (not filename.empty())
			assert(freopen(filename.c_str(), "r", stdin) != nullptr);
	}

	template<typename T>
	inline void operator()(T &x)
	{
		cin >> x;
	}

	template<typename T, typename... Args>
	inline void operator()(T &x, Args &... args)
	{
		read(x), read(args...);
	}
};
Reader read(input_filename);

/* _______ OUTPUT ________*/

class Printer
{
public:
	inline Printer(const string &filename)
	{
		//cout.precision(20);
		//cout << fixed;
		if (not filename.empty())
			assert(freopen(filename.c_str(), "w", stdout) != nullptr);
	}

	template<typename T>
	inline void out(const T x)
	{
		cout << x;
	}

	template<typename T, typename... Args>
	inline void out(const T x, const Args... args)
	{
		out(x), out(args...);
	}

	inline void operator()()
	{
		out('\n');
	}

	template<typename T>
	inline void operator()(const T x)
	{
		out(x), out('\n');
	}

	template<typename T, typename... Args>
	inline void operator()(const T x, const Args... args)
	{
		out(x), out(' '), print(args...);
	};
};
Printer print(output_filename);

/* ________ CODE ________ */

class Solution
{
public:

	int f_floor(int x, int y)
	{
		return min(abs(x - y) * 5, 10 + abs(x - y));
	}

	int n;
	int f_go(int x, int y)
	{
		return min(abs(x - y) * 15, (n - abs(x - y)) * 15);
	}

	inline void solve()
	{
		int m, k, a, b;
		read(n, m, k, a, b);
		--a;
		--b;

		int ak = a % k;
		a /= k;
		int am = a % m;
		a /= m;
		int an = a;

		int bk = b % k;
		b /= k;
		int bm = b % m;
		b /= m;
		int bn = b;

		if (an == bn)
		{
			if (am == bm)
			{
				print(0);
				return;
			}
			else
			{
				print(f_floor(am, bm));
			}
		}
		else
		{
			print(f_floor(am, 0) + f_floor(bm, 0) + f_go(an, bn));
		}
	}

	Solution()
	{
#ifdef ANDREIKKAA
		start = clock();
#endif // ANDREIKKAA
	}

	~Solution()
	{
#ifdef ANDREIKKAA
		print("Time:", (clock() - start) / (ld)CLOCKS_PER_SEC);
#endif // ANDREIKKAA
	}
private:
#ifdef ANDREIKKAA
	time_t start;
#endif // ANDREIKKAA
};

int main()
{
	auto s = new Solution;
	s->solve();
	delete s;
#ifdef ANDREIKKAA
#ifdef _WIN32
	while (true);
#endif // _WIN32
#endif // ANDREIKKAA
}


#include <iostream>
#include <bits/stdc++.h>
using namespace std;
int n, m, k;
int first(long long c)
{
    int a;
    if (c % (m*k) == 0)
        a = c/(m*k);
    else
        a = c/(m*k) + 1;
    return a;
}
int second(long long d, int pod)
{
    int t;
    long long h = d - ((pod - 1)* m * k);
    if (h % k == 0)
        t = h/k;
    else
        t = h/k + 1;
    return t;
}
int main()
{
    freopen("input.txt", "r", stdin);
    long long a, b;
    cin >> n >> m >> k >> a >> b;
    int pod1 = first(a);
    int pod2 = first(b);
    long long ans = 0;
    cout << "pod1 = " << pod1 << endl;
    cout << "pod2 = " << pod2 << endl;
    if (pod1 != pod2)
    {
        ans = ans + 15*(min((max(pod1, pod2) - min(pod1, pod2)), n - (max(pod1, pod2) - min(pod1, pod2))));
    }
    cout << "ans = " << ans << endl;
    int et1 = second(a, pod1);
    int et2 = second(b, pod2);
    cout << "et1 = " << et1 << endl;
    cout << "et2 = " << et2 << endl;
    if (ans == 0)
    {
        if(max(et1, et2) - min(et1, et2) > 2)
            ans = ans + 10 + max(et1, et2) - min(et1, et2);
        else
            ans = ans + 5*(max(et1, et2) - min(et1, et2));
    }
    else
    {
        if(et1 - 1 > 2)
            ans = ans + 10 + et1 - 1;
        else
            ans = ans + 5*(et1 - 1);

        if(et2 - 1 > 2)
            ans = ans + 10 + et2 - 1;
        else
            ans = ans + 5*(et2 - 1);
    }
    cout << ans;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
#define f first
#define s second
#define VI vector<int>
#define LL long long
#define MP make_pair
#define LD long double
#define PB push_back
#define PLL pair <LL, LL>
#define ALL(V) V.begin(),V.end()
#define abs(x) max((x),-(x))
#define PDD pair<LD,LD>
#define VPII vector< PII >
#define siz(V) ((int)V.size())
#define FOR(x, b, e)  for(int x=b;x<=(e);x++)
#define FORD(x, b, e) for(int x=b;x>=(e);x--)
#define REP(x, n)     for(int x=0;x<(n);x++)
#define mini(a,b) a=min(a,b)
#define maxi(a,b) a=max(a,b)
const bool deb =
#ifdef DEB
true;
#define debug cerr << "[LINE:" << __LINE__ << "] " << boolalpha
#else
false;
#define debug if(0) cout
#endif
#define fs(r) r.f, r.s
#define ei else if
template <typename T, typename C>
ostream & operator<<(ostream &os, pair<T, C> x) {
	return os << "<" << x.f << ", " << x.s << ">";
}
template <typename T>
auto operator<<(ostream&os, T x) -> typename enable_if<is_same<decltype(x.begin()), decltype(x.end())>::value && !is_same<T, string>::value, ostream &>::type {
	os << "{";
	int cou = 0;
	for (auto c : x) {
		if (cou++)
			os << ", ";
		os << c;
	}
	return os << "}_" << x.size();
}
#define cr << "][" <<
#define rr << "] = " <<
#define cc << "[" <<
#define ao << ' '
#define name(a) #a << " = " << (a) ao
#define arr(a, i) #a cc #i rr #a cc i rr a[i] ao
#define arr2(a, i, j) #a cc #i cr #j rr #a cc i cr j rr a[i][j] ao
#define arr3(a, i, j, k) #a cc #i cr #j cr #k rr #a cc i cr j cr k rr a[i][j][k] ao
#define arr4(a, i, j, k, q) #a cc #i cr #j cr #k cr #q rr #a cc i cr j cr k cr q rr a[i][j][k][q] ao
#define _2arr(a, b, i) #a cc #b cc #i << "]" rr #a cc #b cc i << "]" rr #a cc b[i] rr a[b[i]] ao
#define _3arr(a, b, c, i) #a cc #b cc #c cc #i << "]]" rr #a cc #b cc #c cc i << "]]" rr #a cc #b cc c[i] << "]" rr  #a cc b[c[i]] rr a[b[c[i]]] ao
#define range(a, i, j) #a cc i << ".." << j rr vector <remove_reference<decltype(a[0])>::type>(&a[i], &a[j + 1]) ao
template <typename T>
string strmask(T r) {
	string ans;
	REP(i, 8 * (int)sizeof(T)) {
		ans += '0' + !!(((T)1 << i) & r);
		if (i % 5 == 4)
			ans += '.';
	}
	return ans;
}
#if 0
ostream & operator<< (ostream & os, __int128_t x) {
	if (x < 0) {
		os << '-';
		x = -x;
	}
	if (x >= 10)
		os << x / 10;
	return os << (int)x % 10;
}
ostream & operator<< (ostream & os, __uint128_t x) {
	if (x >= 10)
		os << x / 10;
	return os << (int)x % 10;
}
#endif
#define nmask(a) #a << " = " << strmask(a) ao
const int mod = 998244353;
#define pow snatheonta
#define rea pair <LL, LD>
const int MN = 1010;
LL pow(LL b, int e) {
	if (e == 0) return 1;
	if (e & 1) return pow(b, e - 1) * b % mod;
	return pow(b * b % mod, e / 2);
}
rea make();
rea operator+(rea a, rea b) {
				         return MP((a.f + b.f) % mod, a.s + b.s);
 }
 rea operator*(rea a, rea b) {
				         return MP((a.f * b.f) % mod, a.s * b.s);
 }
 rea make(int x) {
				         return MP((LL)x, (LD)x);
 }
 rea operator/ (rea a, rea b) {
				         return MP(a.f * pow(b.f, mod - 2) % mod, a.s / b.s);
 }
 rea operator-(rea a, rea b) {
				         return MP((a.f - b.f + mod) % mod, a.s - b.s);
 }
 rea rpow(rea a, int b) {
				         if (b == 0)
												                 return make(1);
																				         if (b % 2)
																												                 return rpow(a, b - 1) * a;
																																				         return rpow(a * a, b / 2);
 }
 rea dp[MN];
 rea pra_best[MN][MN];
 rea p;
 rea psum[MN][MN];
int pairs(int x) {
	return x * (x - 1) / 2;
}
int main() {
	int n, a, b;
	scanf("%d%d%d", &n, &a, &b);
	p = make(a) / make(b);
	dp[1] = make(0);
	bin[0][0] = make(1);
	REP(i, n) {
		bin[i][0] = bin[i][i] = make(1);
		FOR(j, 1, i - 1)
			bin[i - 1][j] + bin[i - 1][j - 1];
	}
	debug << arr2(bin, 10, 5) << arr2(bin, 17, 2) << endl;
	psum[0][0] = make(1);
	pra_best[1][1] = make(1);
	FOR(size, 1, n) {
		FOR(subset, 0, size) {
			if (subset != 0)
				psum[size][subset] = psum[size][subset] + psum[size - 1][subset - 1] * rpow(make(1) - p, size - subset);
			if (subset != size)
				psum[size][subset] = psum[size][subset] + psum[size - 1][subset] * rpow(p, subset);
		}
	}
	dp[1] = make(0);
	FOR(i, 2, n) {
		rea rest = make(1);
		FOR(siz, 1, i - 1) {
			pra_best[i][siz] = pra_best[siz][siz] * psum[i][siz];
			rest = rest - pra_best[i][siz];
			debug << arr2(pra_best, i, siz) << endl;
		}
		pra_best[i][i] = rest;
		debug << arr2(pra_best, i, i) << endl;
	}
	FOR(siz, 2, n) {
		dp[siz] = make(siz * (siz - 1) / 2) * make(1) / (make(1) - pra_best[siz][siz]);
		debug << arr(dp, siz) << endl;
		rea stay = make(1) - pra_best[siz][siz];
		FOR(sub, 1, siz - 1) {
			dp[siz] = dp[siz] + pra_best[siz][sub] / stay * (dp[sub] + dp[siz - sub] - make(pairs(siz - sub)));
			debug << name(sub) << "add " << pra_best[siz][sub] * (dp[sub] + dp[siz - sub] - make(pairs(siz - sub))) << endl;
			debug << arr2(pra_best, siz, sub) << arr(dp, sub) << arr(dp, siz - sub) << name(pairs(siz - sub)) << endl;
		}
		debug << "finally" << arr(dp, siz) << endl;
	}
	debug << arr(dp, n) << endl;
	printf("%lld\n", dp[n].f);
}


#include <bits/stdc++.h>
using namespace std;
#define y1 cgbngfgn
#define pb push_back
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define fir first
#define m_p make_pair
#define sec second
#define files(name) freopen(name".in","r",stdin); freopen (name".out","w",stdout);
#define time pdojegoritg
#define left eorgjrptgj
#define right rtyjtokh
#define int ll
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int arr=3e5+100;
int md=998244353;

map<pair<int,int> > mp;

int bpow(int u, int step)
{
    if (mp.count({u,step}))
        return(mp[{u,step}]);
    if (step==0)
        return(mp[{u,step}]=1);
    if (step%2)
        return(mp[{u,step}]=bpow(u,step-1)*u%md);
    return(mp[{u,step}]=bpow(u*u%md,step/2));
}

int cp[2100][2100],strong[2100],ans[2100];

signed main()
{
    int n;
    cin>>n;
    int p,b;
    cin>>p>>b;
    p*=bpow(b,md-2);
    p%=md;

    for (int i=0;i<=n;i++)
        cp[i][0]=1;

    for (int s=1;s<=n;s++)
        for (int c=1;c<=s;c++)
    {
        cp[s][c]=cp[s-1][c]*bpow((1-p+md)%md,c)%md+cp[s-1][c-1]*bpow(p,s-c)%md;
        cp[s][c]%=md;
    }

    strong[0]=1;
    strong[1]=1;

    for (int i=2;i<=n;i++)
    {
        for (int j=1;j<i;j++)
        {
            strong[i]+=strong[j]*cp[i][j]%md;
            strong[i]%=md;
        }
        strong[i]=(1-strong[i]+md)%md;
    }

    ans[0]=ans[1]=0;

    for (int i=2;i<=n;i++)
    {
        for (int j=1;j<i;j++)
        {
            ans[i]+=strong[j]*cp[i][j]%md*(j*(i-j)%md+j*(j-1)%md*bpow(2,md-2)%md+ans[j]+ans[i-j]);
            ans[i]%=md;
        }
        int k=strong[i]%md;
        ans[i]+=k*i*(i-1)%md*bpow(2,md-2)%md;
        ans[i]%=md;
        ans[i]*=bpow((1-k+md)%md,md-2);
        ans[i]%=md;
    }

    cout<<ans[n];
}


#include <algorithm>
#include <iostream>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <numeric>
#include <cstdio>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

int __gcd(int x, int y) { if(!y) return x; return __gcd(y, x % y); }

#define foreach(i,x) for(type(x)i=x.begin();i!=x.end();i++)
#define FOR(ii,aa,bb) for(int ii=aa;ii<=bb;ii++)
#define ROF(ii,aa,bb) for(int ii=aa;ii>=bb;ii--)

#define sag (k + k + 1)
#define sol (k + k)

#define type(x) __typeof(x.begin())

#define orta ((bas + son) >> 1)
#define sag (k + k + 1)
#define sol (k + k)

#define pb push_back
#define mp make_pair

#define nd second
#define st first

#define endl '\n'

typedef pair < int ,int > pii;

typedef long long ll;

const long long linf = 1e18+5;
int mod = 998244353;
const int logN = 18;
const int inf = 1e9 + 9;

const int N = 2e3 + 6;

// 1p 1-p, 1pp (1-p)/p

int P[N], P1[N], dp2[N][N], aa, P[N], n, m, x, y, z, ssum[N], Z[N], dp[N], p, p1, inv_1p, a, b, k;

int FE(int x, int k) {
	if(!k) return 1;
	int temp = FE(x, k / 2);
	if(k & 1) return temp * (ll) temp % mod * x % mod;
	return (ll) temp * temp % mod;
}

int inverse(int x) { return FE(x, mod - 2); }

int putin(int n, int k) {
	if(k > n) return 0;
	if(k == 0) return 1;
	int &r = dp2[n][k];
	if(r != -1) return r;
	return r = (putin(n - 1, k - 1) * (ll) P1[n - k] % mod + putin(n - 1, k) * (ll) P[k] % mod) % mod;
}

int f(int n) {
	if(n <= 1) return 0;
	int &r = dp[n];
	int coeff = putin(n, n) * (ll) Z[n] % mod;
	int add = n * (n - 1) / 2;
	// f = r + (f + add) * coeff -> f = r + f*coeff + add*coeff -> f = (r + add * coeff) / (1 - coeff)
	r = add * (ll) coeff % mod;
	FOR(k, 1, n - 1) {
		int coeff = putin(n, k) * (ll) Z[k] % mod;
		r = (r + (f(n - k) + f(k) + k * (k - 1) / 2 + (n - k) * k) * (ll) coeff % mod) % mod;
	} return r = (r * (ll) inverse(1 - coeff + mod) % mod);
}

int main() {
	scanf("%d %d %d", &n, &a, &b);
	memset(dp, -1, sizeof dp);
	memset(dp2, -1, sizeof dp2);
	p = a * (ll) inverse(b) % mod;
	p1 = (1 - p + mod) % mod;
	inv_1p = inverse(p1);
	Z[0] = Z[1] = 1;
	FOR(i, 1, n) {
		P[i] = P[i - 1] * (ll) p % mod;
		P1[i] = P1[i - 1] * (ll) p1 % mod;
	}
	FOR(i, 2, n) {
		Z[i] = 0;
		FOR(j, 1, i - 1)
			(Z[i] += Z[j] * (ll) putin(i, j) % mod) %= mod;
		Z[i] = (1 - Z[i] + mod) % mod;
	}
	cout << f(n) << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 2020;
const int mod = 998244353;

int fpow(int x, int y) {
  int ret = 1;
  while(y) {
    if(y & 1) ret = (1LL * ret * x) % mod;
    x = (1LL * x * x) % mod;
    y >>= 1;
  }
  return ret;
}

int n;
int a, b;
int g[N];
int f[N][N]; //// chose j from i pepople so that these j people win everyone else i
int pconnect[N];

int dp[N];

int main(){
  ios_base::sync_with_stdio(false); cin.tie(NULL);

  cin >> n >> a >> b;

  int rp = (1 - p + mod) % mod;

  f[0][0] = 1;
  for(int i = 0; i < N - 1; ++i) {
    for(int j = 0; j <= i; ++j) {
      int winall = fpow(rp, i - j);
      int nowin = fpow(p, j);

      f[i + 1][j] += 1LL * f[i][j] * nowin % mod; /// not choosing i + 1
      f[i + 1][j + 1] += 1LL * f[i][j] * winall % mod;

      f[i + 1][j] %= mod;
      f[i + 1][j + 1] %= mod;
    }
  }

  for(int i = 1; i < N - 1; ++i) {
    pconnect[i] = 1;
    for(int j = 1; j < i; ++j) {
      pconnect[i] -= 1LL * f[i][j] * pconnect[j] % mod;
      pconnect[i] += mod;
      if(pconnect[i] >= mod) pconnect[i] -= mod;
    }
  }

  for(int i = 1; i <= n; ++i) {
    for(int j = 1; j < i; ++j) {
      dp[i] += (dp[j] + dp[i - j] + 1LL * (i - j) * j + (j * (j - 1) / 2) % mod) * 1LL * (1LL * f[i][j] * pconnect[j] % mod) % mod;
      dp[i] %= mod;
    }

    int rate = pconnect[i];
    int kp = (1LL * i * (i - 1) / 2) * rate % mod;

    dp[i] = (dp[i] + kp) * 1LL * fpow((1 - rate + mod) % mod, mod - 2) % mod;

  }

  cout << dp[n] << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;

const int N=1e5+10;

struct point{
	int x,y,id;
	inline point(int _x=0, int _y=0, int _id=0){
		x=_x,y=_y,id=_id;
	}
	inline bool operator<(const point &p) const{
		if (x!=p.x) return x<p.x;
		else if (y!=p.y) return y<p.y;
		else return id<p.id;
	}
}p[N][4];

inline bool solve(set <point> a[4]){
	int size=a[0].size(),
		r[4]={-1e9,-1e9,-1e9,-1e9};
	if (size<=1) return 1;
	set <point>::iterator t[4];
	for (int i=0;i<4;i++)
		t[i]=a[i].begin();
	for (int i=1;i<size;i++)
		for (int j=0;j<4;j++){
			r[j]=max(r[j],t[j]->y); t[j]++;
			if (t[j]->x>=r[j]){
				set <point> b[4];
				for (auto tt=a[j].begin();tt!=t[j];){
					point *tmp=p[tt->id]; tt++;
					for (int k=0;k<4;k++){
						a[k].erase(tmp[k]);
						b[k].insert(tmp[k]);
					}
				}
				return solve(b)&&solve(a);
			}
		}
	return 0;
}

int main(){
	int n; scanf("%d",&n);
	set <point> a[4];
	for (int i=1;i<=n;i++){
		int x1,y1,x2,y2;
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		p[i][0]=point(x1,x2,i);
		a[0].insert(p[i][0]);
		p[i][1]=point(-x2,-x1,i);
		a[1].insert(p[i][1]);
		p[i][2]=point(y1,y2,i);
		a[2].insert(p[i][2]);
		p[i][3]=point(-y2,-y1,i);
		a[3].insert(p[i][3]);
	}
	puts(solve(a)?"YES":"NO");
	return 0;
}


#pragma GCC optimize("O2")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx,avx2,sse,sse2,ssse3,tune=native")
#include<bits/stdc++.h>
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define pb push_back
using namespace std;
using ll = long long;
//using arr = array;
using pi = pair<int, int>;
using vi = vector<ll>;
using vpi = vector<pi>;
using ld = long double;
#include<bits/extc++.h>
using namespace __gnu_pbds;
template<class T>
using oset = tree<int, null_type, T, rb_tree_tag, tree_order_statistics_node_update>;
const int maxn = 1<<18, mod = 1e9 + 7, lg = 19;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int mx = maxn-1;
struct segtree {
	struct node {
		node *l, *r;
		int lazy;
		pi val;
		node(int x = 0, int p = -1) : val(x, p), lazy(0), l(0), r(0) {};
	};
	using pnode = node*;
	deque<node> karan;
	pnode newnode(int x = 0, int p = -1) {
		karan.emplace_back(x, p);
		return &karan.back();
	}
	pnode rt= nullptr;
	void clear() {
		rt = nullptr;
	}
	void push(pnode &v, int l, int r) {
		if(!v) return;
		v->val.first += v->lazy;
		if(l != r) {
		if(!v->l) v->l = newnode(0, l);
		if(!v->r) v->r = newnode(0, 1 + (l+r)/2);
		v->l->lazy += v->lazy;
		v->r->lazy += v->lazy;
		}
		v->lazy = 0;
	}
	pi get(int l, int r) {
		if(l>r) return {1<<30, -1};
		return get(0, mx, l, r, rt);
	}
	pi get(int l, int r, int ql, int qr, pnode &v) {
		push(v, l, r);
		if(r < ql || qr < l) return {1<<30, -1};
		if(!v) v = newnode(0, l);
		if(ql <= l && r <= qr) return v->val;
		int mid = (l+r)/2;
		return min(get(l, mid, ql, qr, v->l), get(mid+1, r, ql, qr, v->r));
	}
	void upd(int l, int r, int x) {
		if(l>r) return;
		upd(0, mx, l, r, x, rt);
	}
	void upd(int l, int r, int ql, int qr, int x, pnode &v) {
		push(v, l, r);
		if(r < ql || qr < l) return;
		//cout << l << " " << r << " " << ql << " " << qr << '\n';
		if(!v) v = newnode(0, l);
		if(ql <= l && r <= qr) {
			v->lazy = x;
			push(v, l, r);
			return;
		}
		int mid = (l+r)/2;
		upd(l, mid, ql, qr, x, v->l);
		upd(mid + 1, r, ql, qr, x, v->r);
		v->val = min(v->l?v->l->val:pi{0, l}, v->r?v->r->val:pi{0, mid+1});
	}
};
int n, lx[maxn], rx[maxn], ly[maxn], ry[maxn];
#define lesspp(x, y, a, b) (x<a||(x==a&&y<b))
struct xcmp {
	bool operator() (const int &i, const int &j) const {
		return lesspp(lx[i], ly[i], lx[j], ly[j]);
	}
};
struct ycmp {
	bool operator() (const int &i, const int &j) const {
		return lesspp(ly[i], lx[i], ly[j], lx[j]);
	}
};
void dfs(oset<xcmp> x, oset<ycmp> y) {
	if(x.size()<=1) return;
	segtree cx, cy;
	for(auto i : x) {
		cx.upd(lx[i]+1, rx[i]-1, 1);
		//cout <<"x["<< lx[i]+1 << " " << rx[i]-1 << "] " << 1 << endl;
		cy.upd(ly[i]+1, ry[i]-1, 1);
		//cout <<"y["<< ly[i]+1 << " " << ry[i]-1 << "] " << 1 << endl;
		//for(int i = 0; i < 3; i++) cout << cy.get(i, i).first << " ";cout << endl;
		//return;//remove
	}
	//cout << cx.rt->val.first << " " << cx.rt->val.second << '\n';
	//cout << cy.rt->val.first << " " << cy.rt->val.second << '\n';
	//for(int i = 0; i < 3; i++) cout << cx.get(i, i).first << " ";cout << endl;
	//for(int i = 0; i < 3; i++) cout << cy.get(i, i).first << " ";cout << endl;
	//cout << x.size() << " " << y.size() << " <3" << endl;
	while(x.size()>1) {
		auto p = cx.get(lx[*x.begin()]+1, lx[*x.rbegin()]);
		//cout << p.first << " " << p.second << " cut < " << lx[*x.rbegin()] << endl;
		if(p.first==0) {
			int cut = p.second;
			int LEQ = x.order_of_key(cut+1);
			oset<xcmp> nx;
			oset<ycmp> ny;
			if(lx[x.find_by_order(x.size()/2)] >= cut) {
				//cout << "xxcut " << cut << endl;
				while(lx[*x.begin()] < cut) {
					int t = *x.begin();
					x.erase(t);
					y.erase(t);
					cx.upd(lx[t]+1, rx[t]-1, -1);
					cy.upd(ly[t]+1, ry[t]-1, -1);
					nx.insert(t);
					ny.insert(t);
				}
				//cout << nx.size() << " " << ny.size() << '\n';exit(0);
			} else {
				//cout << "HER" << cut<<endl;
				while(lx[*x.rbegin()] >= cut) {
					int t = *x.rbegin();
					//cout << "HERE"<<endl;
					x.erase(t);
					y.erase(t);
					//cout << "HERE1"<<endl;
					cx.upd(lx[t]+1, rx[t]-1, -1);
					cy.upd(ly[t]+1, ry[t]-1, -1);
					//cout << "HERE2"<<endl;
					nx.insert(t);
					ny.insert(t);
					//cout << "HERE3"<<endl;
				}
			}
			//return;//REMOVE
			dfs(nx, ny);
			continue;
		}

		p = cy.get(ly[*y.begin()]+1, ly[*y.rbegin()]);
		if(p.first==0) {
			int cut = p.second;
			//cout << "ycut " << endl;
			//cout << cut << " ";
			oset<xcmp> nx;
			oset<ycmp> ny;
			if(ly[y.find_by_order(y.size()/2)] >= cut) {
				//cout << "HER" << cut<<endl;
				while(ly[*y.begin()] < cut) {
					int t = *y.begin();
					x.erase(t);
					y.erase(t);
					cx.upd(lx[t]+1, rx[t]-1, -1);
					cy.upd(ly[t]+1, ry[t]-1, -1);
					nx.insert(t);
					ny.insert(t);
				}
			//cout << nx.size() << " " << ny.size() << '\n';
			//exit(0);
			} else {
				while(ly[*y.rbegin()] >= cut) {
					int t = *y.rbegin();
					x.erase(t);
					y.erase(t);
					cx.upd(lx[t]+1, rx[t]-1, -1);
					cy.upd(ly[t]+1, ry[t]-1, -1);
					nx.insert(t);
					ny.insert(t);
				}
			}
			//return;//REMOVE
			dfs(nx, ny);
			continue;
		}
		cout << "NO", exit(0);
	}
	if(x.size()>1) {cout << "NO", exit(0);}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	oset<xcmp> x;
	oset<ycmp> y;
	vi xc, yc;
	for(int i = 0; i < n; i++) {
		cin >> lx[i] >> ly[i] >> rx[i] >> ry[i];
		xc.pb(lx[i]), xc.pb(rx[i]), yc.pb(ly[i]), yc.pb(ry[i]);
	}
	sort(all(xc)), xc.erase(unique(all(xc)), xc.end());
	sort(all(yc)), yc.erase(unique(all(yc)), yc.end());
	for(int i = 0; i < n; i++) {
		lx[i] = lower_bound(all(xc), lx[i]) - xc.begin();
		rx[i] = lower_bound(all(xc), rx[i]) - xc.begin();
		ly[i] = lower_bound(all(yc), ly[i]) - yc.begin();
		ry[i] = lower_bound(all(yc), ry[i]) - yc.begin();
	}
	for(int i = 0; i < n; i++) x.insert(i), y.insert(i);
	dfs(x, y);
	cout << "YES";
	return 0;
}


A Story of One Country#include<bits/stdc++.h>
#define M 100005
using namespace std;
struct node{
	int x,y,p;
	bool operator <(const node _) const{
		if(x==_.x&&y==_.y)return p<_.p;
		if(x==_.x)return y<_.y;
		return x<_.x;
	}
} g[4][M];
int f[4][M],n;
set<node>x[4];
const int inf=2e9;
int solve(set<node> t[4])
{
	int n=t[0].size();
	set<node>s[4];
	set<node>::iterator it[4];
	for(int i=0;i<4;i++)  it[i]=t[i].begin();
	if(n==1)  return 1;
	int mx[4]={-inf,-inf,-inf,-inf};
	for(int i=0;i<n;i++)
    {
		for(int j=0;j<4;j++)
        {
			f[j][i]=it[j]->p;
			if(i&&it[j]->x>=mx[j])
            {
				for(int k=0;k<i;k++)
					for(int l=0;l<4;l++)
                    {
						s[l].insert(g[l][f[j][k]]);
						t[l].erase(g[l][f[j][k]]);
					}
				return solve(s)&&solve(t);
			}
			mx[j]=max(mx[j],it[j]->y);
			it[j]++;
		}
	}
	return 0;
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
    {
		int a,b,c,d;
		scanf("%d%d%d%d",&a,&b,&c,&d);

		g[0][i]=(node)<%a,c,i%>;
		x[0].insert(g[0][i]);

		g[1][i]=(node) <%-c,-a,i%>;
		x[1].insert(g[1][i]);

		g[2][i]=(node) <%b,d,i%>;
		x[2].insert(g[2][i]);

		g[3][i]=(node) <%-d,-b,i%>;
		x[3].insert(g[3][i]);
	}
	puts(solve(x)?"yes":"no");
	return 0;
}


#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
#define //////DBG(v) //cerr << #v << " = " << (v) << endl;

struct Rect {
	int x1, y1, x2, y2;
};

const int MxN = (int) 1e5 + 9;
Rect a[MxN + 9];

auto compX1 = [](const int i, const int j) {
	int diff = a[i].x1 - a[j].x1;
	return diff ? diff < 0 : i < j;
};
auto compX2 = [](const int i, const int j) {
	int diff = a[i].x2 - a[j].x2;
	return diff ? diff > 0 : i < j;
};
auto compY1 = [](const int i, const int j) {
	int diff = a[i].y1 - a[j].y1;
	return diff ? diff < 0 : i < j;
};
auto compY2 = [](const int i, const int j) {
	int diff = a[i].y2 - a[j].y2;
	return diff ? diff > 0 : i < j;
};

template<class T> bool f(T first, T last);

bool f(set<int, decltype(compX1)> &sx1, set<int, decltype(compX2)> &sx2, set<int, decltype(compY1)> &sy1, set<int, decltype(compY2)> &sy2) {
	assert(sx1.size() == sx2.size());
	assert(sy1.size() == sy2.size());
	assert(sx1.size() == sy1.size());
	const int sz = (int) sx1.size();
	if (sz <= 1) {
		assert(sz == 1);
		return true;
	}

	auto itX1 = sx1.begin();
	auto itX2 = sx2.begin();
	auto itY1 = sy1.begin();
	auto itY2 = sy2.begin();

	static const ll Inf = (int) 1e9 + 9;

	int mx1 = -Inf;
	int mx2 = +Inf;
	int my1 = -Inf;
	int my2 = +Inf;

	for (int rep = 0; rep < sz / 2; ++rep) {
		mx1 = max(mx1, a[*itX1].x2);
		mx2 = min(mx2, a[*itX2].x1);
		my1 = max(my1, a[*itY1].y2);
		my2 = min(my2, a[*itY2].y1);

		++itX1, ++itX2, ++itY1, ++itY2;

		if (mx1 <= a[*itX1].x1) {
			//////DBG(mx1)
			//////DBG(a[*itX1].x1)

			//cerr << "sep x1" << endl;

			set<int, decltype(compX1)> sx1N(compX1);
			set<int, decltype(compX2)> sx2N(compX2);
			set<int, decltype(compY1)> sy1N(compY1);
			set<int, decltype(compY2)> sy2N(compY2);

			while (sx1.begin() != itX1) {
				const int x = *sx1.begin();

				sx1.erase(x);
				sx2.erase(x);
				sy1.erase(x);
				sy2.erase(x);

				sx1N.insert(x);
				sx2N.insert(x);
				sy1N.insert(x);
				sy2N.insert(x);
			}

			return f(sx1N, sx2N, sy1N, sy2N) && f(sx1, sx2, sy1, sy2);
		}
		if (mx2 >= a[*itX2].x2) {
			//cerr << "sep x2" << endl;

			set<int, decltype(compX1)> sx1N(compX1);
			set<int, decltype(compX2)> sx2N(compX2);
			set<int, decltype(compY1)> sy1N(compY1);
			set<int, decltype(compY2)> sy2N(compY2);

			while (sx2.begin() != itX2) { // 2 changes
				const int x = *sx2.begin(); // 1 change

				sx1.erase(x);
				sx2.erase(x);
				sy1.erase(x);
				sy2.erase(x);

				sx1N.insert(x);
				sx2N.insert(x);
				sy1N.insert(x);
				sy2N.insert(x);
			}

			return f(sx1N, sx2N, sy1N, sy2N) && f(sx1, sx2, sy1, sy2);
		}
		if (my1 <= a[*itY1].y1) {
			//cerr << "sep y1" << endl;

			set<int, decltype(compX1)> sx1N(compX1);
			set<int, decltype(compX2)> sx2N(compX2);
			set<int, decltype(compY1)> sy1N(compY1);
			set<int, decltype(compY2)> sy2N(compY2);

			while (sy1.begin() != itY1) { // 2 changes
				const int x = *sy1.begin(); // 1 change

				sx1.erase(x);
				sx2.erase(x);
				sy1.erase(x);
				sy2.erase(x);

				sx1N.insert(x);
				sx2N.insert(x);
				sy1N.insert(x);
				sy2N.insert(x);
			}

			return f(sx1N, sx2N, sy1N, sy2N) && f(sx1, sx2, sy1, sy2);
		}
		if (my2 >= a[*itY2].y2) {
			//cerr << "sep y2" << endl;

			set<int, decltype(compX1)> sx1N(compX1);
			set<int, decltype(compX2)> sx2N(compX2);
			set<int, decltype(compY1)> sy1N(compY1);
			set<int, decltype(compY2)> sy2N(compY2);

			while (sy2.begin() != itY2) { // 2 changes
				const int x = *sy2.begin(); // 1 change

				sx1.erase(x);
				sx2.erase(x);
				sy1.erase(x);
				sy2.erase(x);

				sx1N.insert(x);
				sx2N.insert(x);
				sy1N.insert(x);
				sy2N.insert(x);
			}

			return f(sx1N, sx2N, sy1N, sy2N) && f(sx1, sx2, sy1, sy2);
		}
	}

	return false;
}

template<class It> bool f(It first, It last) {
	set<int, decltype(compX1)> sx1(compX1);
	set<int, decltype(compX2)> sx2(compX2);
	set<int, decltype(compY1)> sy1(compY1);
	set<int, decltype(compY2)> sy2(compY2);
	while (first < last) {
		sx1.insert(*first);
		sx1.insert(*first);
		sx1.insert(*first);
		sx1.insert(*first);
		++first;
	}
	return f(sx1, sx2, sy1, sy2);
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr), cout.tie(nullptr);

	int n;
	cin >> n;
	for (int i = 0; i < n; ++i)
		cin >> a[i].x1 >> a[i].y1 >> a[i].x2 >> a[i].y2;

	set<int, decltype(compX1)> sx1(compX1);
	set<int, decltype(compX2)> sx2(compX2);
	set<int, decltype(compY1)> sy1(compY1);
	set<int, decltype(compY2)> sy2(compY2);

	for (int x = 0; x < n; ++x) {
		sx1.insert(x);
		sx2.insert(x);
		sy1.insert(x);
		sy2.insert(x);
	}

	const bool yes = f(sx1, sx2, sy1, sy2);
	cout << (yes ? "YES" : "NO");
	return 0;
}


#include <bits/stdc++.h>

#define FASTIO

#ifdef FASTIO
#define scanf abacaba
#define printf abacaba
#endif

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

using namespace std;
using bb = bitset<C>;

const int C2 = 19;
const int C = 9 * 20 + 1;

vector<bb> vv;
unordered_set<bb> mapa1, mapa2;

bool cmp(const bb &a, const bb &b){
	for (int i = 0; i < 9 * 20; ++i){
		if (a[i] < b[i])
			return 1;
		if (b[i] < a[i])
			return 0;
	}
	return 0;
}

unordered_map<bb, int> mm;

int upd(int x, int j){
	bb cur = (vv[x] << j) | (vv[x] >> j);
	for (int k = 0; k < j; ++k)
		if (vv[x][k])
			cur[j - k] = 1;
	auto it = mm.find(cur);
	if (it == mm.end())
		return -1;
	return it->second;
}
const int MX = 50000;

int go[MX][10];
ll dp[MX][10][20];
int nl;

ll get(ll x, int k) {
	vector<int> dg;
	for (int i = 0; i < C2; ++i)
		dg.push_back(x % 10), x /= 10;
	ll ans = 0;
	ll cur = nl;
	for (int i = C2 - 1; i >= 0; --i){
		for (int j = 0; j < dg[i]; ++j){
			ll tmp = go[cur][j];
			ans += dp[tmp][k][i];
		}
		cur = go[cur][dg[i]];
	}
	return ans;
}

int av[MX][10];

int main() {
	#ifdef FASTIO
		ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	#endif
	bb tmp;
	tmp[0] = 1;
	mapa1.insert(tmp);
	for (int i = 0; i < C2; ++i){
		mapa2.clear();
		for (auto msk: mapa1){
			for (int j = 0; j <= 9; ++j){
				bb cur = (msk << j) | (msk >> j);
				for (int k = 0; k < j; ++k)
					if (msk[k])
						cur[j - k] = 1;
				mapa2.insert(cur);
			}
		}
		mapa1 = mapa2;
	}
	for (auto x: mapa1)
		vv.push_back(x);
	sort(vv.begin(), vv.end(), cmp);
	for (int i = 0; i < vv.size(); ++i)
		mm[vv[i]] = i;
	nl = mm[tmp];
	av[nl][0] = 1;
	for (int i = 0; i < vv.size(); ++i){
		go[i][0] = i;
		for (int j = 1; j <= 9; ++j){
			go[i][j] = upd(i, j);
		}
		for (int j = 0; j <= 9; ++j)
			if (vv[i][j])
				av[i][j] = 1;
	}
	for (int i = vv.size() - 1; i >= 0; --i){
		int x = 0;
		while (!av[i][x]) {
			++x;
		}
		for (int j = x; j <= 9; ++j)
			dp[i][j][0] = 1;
	}
	for (int ad = 1; ad <= C2; ++ad){
		for (int i = 0; i < vv.size(); ++i){
			for (int j = 0; j <= 9; ++j){
				if (go[i][j] == -1)
					continue;
				for (int k = 0; k <= 9; ++k){
					dp[i][k][ad] += dp[go[i][j]][k][ad - 1];
				}
			}
		}
	}
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i){
		ll l, r;
		int k;
		cin >> l >> r >> k;
		cout << get(r + 1, k) - get(l, k) << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

using namespace std;
using bb = bitset<C>;

const int C2 = 19;
const int C = 9 * 20 + 1;

vector<bb> vv;
unordered_set<bb> mapa1, mapa2;

bool cmp(const bb &a, const bb &b){
	for (int i = 0; i < 9 * 20; ++i){
		if (a[i] < b[i])
			return 1;
		if (b[i] < a[i])
			return 0;
	}
	return 0;
}

unordered_map<bb, int> mm;

int upd(int x, int j){
	bb cur = (vv[x] << j) | (vv[x] >> j);
	for (int k = 0; k < j; ++k)
		if (vv[x][k])
			cur[j - k] = 1;
	auto it = mm.find(cur);
	if (it == mm.end())
		return -1;
	return it->second;
}
const int MX = 50000;

int go[MX][10];
ll dp[MX][10][20];
int nl;

ll get(ll x, int k) {
	vector<int> dg;
	for (int i = 0; i < C2; ++i)
		dg.push_back(x % 10), x /= 10;
	ll ans = 0;
	ll cur = nl;
	for (int i = C2 - 1; i >= 0; --i){
		for (int j = 0; j < dg[i]; ++j){
			ll tmp = go[cur][j];
			ans += dp[tmp][k][i];
		}
		cur = go[cur][dg[i]];
	}
	return ans;
}

int av[MX][10];

int main() {

	bb tmp;
	tmp[0] = 1;
	mapa1.insert(tmp);
	for (int i = 0; i < C2; ++i){
		mapa2.clear();
		for (auto msk: mapa1){
			for (int j = 0; j <= 9; ++j){
				bb cur = (msk << j) | (msk >> j);
				for (int k = 0; k < j; ++k)
					if (msk[k])
						cur[j - k] = 1;
				mapa2.insert(cur);
			}
		}
		mapa1 = mapa2;
	}
	for (auto x: mapa1)
		vv.push_back(x);
	sort(vv.begin(), vv.end(), cmp);
	for (int i = 0; i < vv.size(); ++i)
		mm[vv[i]] = i;
	nl = mm[tmp];
	av[nl][0] = 1;
	for (int i = 0; i < vv.size(); ++i){
		go[i][0] = i;
		for (int j = 1; j <= 9; ++j){
			go[i][j] = upd(i, j);
		}
		for (int j = 0; j <= 9; ++j)
			if (vv[i][j])
				av[i][j] = 1;
	}
	for (int i = vv.size() - 1; i >= 0; --i){
		int x = 0;
		while (!av[i][x]) {
			++x;
		}
		for (int j = x; j <= 9; ++j)
			dp[i][j][0] = 1;
	}
	for (int ad = 1; ad <= C2; ++ad){
		for (int i = 0; i < vv.size(); ++i){
			for (int j = 0; j <= 9; ++j){
				if (go[i][j] == -1)
					continue;
				for (int k = 0; k <= 9; ++k){
					dp[i][k][ad] += dp[go[i][j]][k][ad - 1];
				}
			}
		}
	}
	int n;
	cin >> n;
	for (int i = 0; i < n; ++i){
		ll l, r;
		int k;
		cin >> l >> r >> k;
		cout << get(r + 1, k) - get(l, k) << "\n";
	}
	return 0;
}


#include<cstdio>
#include<bitset>
#include<unordered_map>
using namespace std;
typedef long long LL;
const int maxn=5e4+2;
const int maxm=20+2;
const int B=200+2;
int cnt=1;
bitset<B> a[maxn];
int to[maxm][maxn];
bool vis[maxm][maxn];
map<bitset<B>,int> mp;
LL dp[maxm][maxm][maxn];
void DP(){
	for (int i=1;i<maxm-1;i++){
		int j=0;
		for (;j<10;j++) if (a[i][j]) break;
		for (;j<10;j++) dp[0][i][j]=1;
	}
	for (int i=1;i<maxm-1;i++)
		for (int j=1;j<=cnt;j++)
			if (vis[maxm-1-i][j])
				for (int k=0;k<10;k++)
					for (int l=0;l<10;l++)
						dp[i][l][j]+=dp[i-1][l][to[j][k]];
}
int bit[maxm];
LL solve(LL x,int k){
	if (x==0) return 1;
	int len=0;
	while (x){
		bit[len++]=x%10;
		x/=10;
	}
	int u=1;
	LL ret=0;
	for (int i=len-1;i>=0;i--){
		for (int j=0;j<bit[i]+(i==0);j++) ret+=dp[i][k][to[u][j]];
		u=to[u][bit[i]];
	}
	return ret;
}
int main(){
	bitset<B> Bit;
	Bit.set(0);
	mp[Bit]=1;
	a[1]=Bit;
	vis[0][1]=1;
	for (int i=1;i<maxm;i++)
		for (int u=1;u<=cnt;u++)
			if (vis[i-1][u])
				for (int j=0;j<10;j++){
					if (!to[u][j])
						if (!j) to[u][j]=u;
						else{
							Bit.reset();
							for (int k=0;k<B;k++)
								if (a[u][k]) Bit[k-j]=1;
							for (int k=0;k<B-j;k++)
								if (a[u][k]) Bit[k+j]=1;
							for (int k=1;k<j;k++)
								if (a[u][k]) Bit[j-k]=1;
							if (mp.count(Bit)) to[u][j]=mp[Bit];
							else{
								to[u][j]=mp[Bit]=++cnt;
								a[cnt]=Bit;
							}
						}
					vis[i][to[u][j]]=true;
				}
	DP();
	int kase;
	scanf("%d",&kase);
	while (kase--){
		LL l,r;
		int k;
		scanf("%I64d%I64d%d",&l,&r,&k);
		printf("%I64d\n",solve(r,k)-solve(l-1,k));
	}
	return 0;
}


#include<bits/stdc++.h>
#define mo (3e18ll)
#define ll long long
#define gc getchar
using namespace std;

void upd(ll &x,ll y){
	(x+=y)>=mo?x-=mo:233;
}
struct node{
	int nxt;
	ll sta,v[10];
	node(){
		nxt=0;
		memset(v,0,sizeof(v));
	}
};
struct state{
	#define Mo 100007
	vector<node> nodes;
	int head[Mo];
	state(){
		memset(head,-1,sizeof(head));
	}
	size_t size() const{
		return nodes.size();
	}
	void sum(){
		for (int i=0;i<nodes.size();i++)
			for (int j=1;j<=9;j++)
				upd(nodes[i].v[j],nodes[i].v[j-1]);
	}
	void update(int at,ll key,ll v){
		int tmp=key%Mo;
		for (int i=head[tmp];i!=-1;i=nodes[i].nxt)
			if (nodes[i].sta==key){
				upd(nodes[i].v[at],v);
				return;
			}
		node now;
		now.nxt=head[tmp];
		head[tmp]=nodes.size();
		now.v[at]=v;
		now.sta=key;
		nodes.push_back(now);
	}
	ll find(int at,ll key){
		int tmp=key%Mo;
		for (int i=head[tmp];i!=-1;i=nodes[i].nxt)
			if (nodes[i].sta==key)
				return nodes[i].v[at];
		return 0;
	}
}f[11][32];
ll c[2][32],bit[15];
bitset<200> vis[15],pre[200],tmp;

struct big{
	int a[35],len;
	void read(){
		memset(a,0,sizeof(a));
		len=0;
		char ch=gc();
		for (;ch<'0'||ch>'9';ch=gc());
		for (;ch>='0'&&ch<='9';ch=gc())
			a[len++]=ch-48;
	}
	int mod(){
		int ans=0;
		for (int i=0;i<len;i++)
			ans=(10ll*ans+a[i])%mo;
		return ans;
	}
	void plus(){
		a[len-1]++;
		for (int i=len-1;i>=1;i--)
			a[i-1]+=a[i]/10,a[i]%=10;
		if (a[0]>9){
			a[len]=1;
			for (int i=0;i<len;i++)
				a[i]=0;
			len++;
		}
	}
}L,R;

int sum[40],times=0;
void dfs(int dep,int cnt,int sum,ll msk){
	int mx=sum+(18-cnt)*9;
	tmp=pre[mx>>1];
	if (sum>>1) tmp^=pre[(sum>>1)-1];
	if ((vis[dep-1]&tmp)==tmp) return;
	if (dep==10){
		for (int i=sum>>1;i>=0;i--)
			if (vis[dep-1][i]){
				int dif=sum-i-i;
				if (dif>1){
					::sum[cnt]++;
					f[dif][0].update(0,msk,1);
				}
				break;
			}
		return;
	}
	vis[dep]=vis[dep-1];
	dfs(dep+1,cnt,sum,msk);
	for (;cnt<18;){
		vis[dep]|=vis[dep]<<dep;
		dfs(dep+1,++cnt,sum+=dep,msk+=bit[dep]);
	}
}
ll solve(int dif,big lim){
	ll ans=0,msk=0;
	int len=lim.len;
	state *F=f[dif];
	for (int i=0;i<len;i++)
		if (len-i>30){
			for (int j=0;j<lim.a[i];j++)
				ans+=F[len-i].find(9,msk);
		}
		else if (lim.a[i]){
			ans+=F[len-i].find(lim.a[i]-1,msk);
			msk+=bit[lim.a[i]];
		}
	return ans;
}
ll solve2(big lim){
	int len=lim.len;
	ll ans=0; int part=0;
	for (int i=0;i<len;i++){
		int odd=lim.a[i]>>1,even=lim.a[i]-odd;
		ans+=c[part][len-1-i]*odd+c[part^1][len-1-i]*even;
		part^=lim.a[i]&1;
	}
	return ans;
}
inline ll read(){
	ll x=0;
	char ch=gc();
	for (;ch<'0'||ch>'9';ch=gc());
	for (;ch>='0'&&ch<='9';ch=gc())
		x=x*10-48+ch;
	return x;
}
int main(){
	pre[0][0]=1;
	for (int i=1;i<=190;i++)
		pre[i]=pre[i-1],pre[i][i]=1;
	c[0][0]=1;
	for (int i=1;i<=18;i++)
		c[0][i]=c[1][i]=5ll*(c[0][i-1]+c[1][i-1])%mo;
	bit[1]=1;
	for (int i=2;i<10;i++)
		bit[i]=bit[i-1]<<5;
	vis[0].set(0);
	dfs(1,0,0,0);
	for (int i=2;i<10;i++){
		f[i][0].sum();
		for (int j=0;j<18;j++){
			state &cur=f[i][j],&nxt=f[i][j+1];
			for (int id=0,sz=cur.size();id<sz;id++){
				int cnt=j; ll way=cur.nodes[id].v[9];
				ll msk=cur.nodes[id].sta,tmp=msk;
				for (int k=1;k<10;k++,tmp>>=5){
					int rem=tmp&31;
					if (!rem) continue;
					cnt+=rem; nxt.update(k,msk-bit[k],way);
				}
				if (cnt<18)
					nxt.update(0,msk,way);
			}
			nxt.sum();
		}
	}
	int Q=read();
	while (Q--){
		L.read(); R.read();
		R.plus();
		int k=read();
		ll ans=R.mod()-L.mod();
		if (!k){
			ans-=solve2(R)-solve2(L);
			for (int i=2;i<10;i+=2)
				ans-=solve(i,R)-solve(i,L);
		}
		else
			for (int i=k+1;i<10;i++)
				ans-=solve(i,R)-solve(i,L);
		printf("%lld\n",(ans%mo+mo)%mo);
	}
}


#include <bits/stdc++.h>
using namespace std;
inline void update(int64_t &A, int64_t B){
  if(A > B) A = B;
}
int64_t dp[2][500][500][2];
vector<pair<int, int>> robot[500][500];
bool good[500000][4];
bitset<500000> good[4];
int d[500000], e[500000];
signed main(){
  ios_base::sync_with_stdio(0); cin.tie(0);
  // freopen("FDT.txt", "r", stdin);
  int n, m, k;
  cin >> n >> m >> k;
  vector<int> dx = {0, 1, 1, 0}, dy = {0, -1, 0, 1};
  int cap = max(m, n);
  for(int i = 0; i < k; i ++){
    int x, y, t;
    cin >> x >> y >> d[i] >> t >> e[i];
    for(int zi = 0; zi < 4; zi ++){
      int nx = x + dx[zi] * d[i], ny = y + dy[zi] * d[i];
      if(zi + t <= nx + ny && (zi + t) % 4 == (nx + ny) % 4){
        robot[nx][ny].push_back({i, zi});
        good[zi].set(i);
      }
    }
  }
  for(int X = 0; X < 2; ++ X)
    for(int Y = 0; Y < m; ++ Y)
      for(int W = 0; W < cap; ++ W)
        for(int vert = 0; vert < 2; ++ vert)
          dp[X][Y][W][vert] = LLONG_MAX;
  dp[0][0][0][0] = dp[0][0][0][1] = 0;
  int64_t ans = LLONG_MAX;
  for(int X = 0; X < n; ++ X){
    int cur = X & 1; int nxt = 1 - cur;
    for(int Y = 0; Y < m; ++ Y){
      for(int W = 0; W < cap; ++ W){
        for(int vert = 0; vert < 2; vert ++){
          if(W > (vert ? X: Y) || dp[cur][Y][W][vert] == LLONG_MAX) break;
          if(Y < m - 1){
            int right = (vert ? 0: W) + 1;
            int64_t smash = 0;
            for(auto &[id, zi]: robot[X][Y + 1]){
              if(zi == 2 && right >= d[id] && good[1][id]) continue;
              if(zi == 3 && right >= d[id] && good[0][id]) continue;
              smash += e[id];
            }
            update(dp[cur][Y + 1][right][0], dp[cur][Y][W][vert] + smash);
            update(dp[cur][Y + 1][0][1], dp[cur][Y][W][vert] + smash);
          }
          if(X < n - 1){
            int down = (vert ? W: 0) + 1;
            int64_t smash = 0;
            for(auto &[id, zi]: robot[X + 1][Y]){
              if(zi == 2 && down >= d[id] && good[0][id]) continue;
              smash += e[id];
            }
            update(dp[nxt][Y][down][1], dp[cur][Y][W][vert] + smash);
            update(dp[nxt][Y][0][0], dp[cur][Y][W][vert] + smash);
          }
        }
      }
    }
    if(X == n - 1){
      for(int W = 0; W < cap; ++ W)
        for(int vert = 0; vert < 2; ++ vert)
          update(ans, dp[cur][m - 1][W][vert]);
      break;
    }
    for(int Y = 0; Y < m; ++ Y)
      for(int W = 0; W < cap; ++ W)
        for(int vert = 0; vert < 2; ++ vert)
          dp[cur][Y][W][vert] = LLONG_MAX;
  }
  cout << ans;
  return 0;
}


#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma comment(linker, "/stack:200000000")
using namespace std;
#define F first
#define S second
#define EB emplace_back
#define MP make_pair
#define all(o) (o).begin(), (o).end()
#define mset(m,v) memset(m,v,sizeof(m))
#define fr(i,n) for(lli i=0;i<(n);++i)
#define rep(i,a,b) for(lli i=a;i<=b;++i)
#define per(i,a,b) for(lli i=a;i>=b;i--)
#define remin(a,b) (a=min((a),(b)))
#define remax(a,b) (a=max((a),(b)))
#define sz(x) (lli)(x).size()
#define endl '\n'
typedef long long lli;        typedef long double ld;
typedef pair<lli,lli> ii;     typedef vector<lli> vi;
typedef vector<ii> vii;       typedef vector<vi> graph;
long long MOD=1000000007;     long double EPS=1e-9;
#ifndef ONLINE_JUDGE
#define debarr(a,n) cerr<<#a<<" : ";for(int i=0;i<n;i++) cerr<<a[i]<<" "; cerr<<endl;
#define debmat(mat,row,col) cerr<<#mat<<" :\n";for(int i=0;i<row;i++) {for(int j=0;j<col;j++) cerr<<mat[i][j]<<" ";cerr<<endl;}
#define pr(...) dbs(#__VA_ARGS__, __VA_ARGS__)
template <class S, class T>ostream& operator <<(ostream& os, const pair<S, T>& p) {return os << "(" << p.first << ", " << p.second << ")";}
template <class T>ostream& operator <<(ostream& os, const vector<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T>ostream& operator <<(ostream& os, const unordered_set<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class S, class T>ostream& operator <<(ostream& os, const unordered_map<S, T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T>ostream& operator <<(ostream& os, const set<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T>ostream& operator <<(ostream& os, const multiset<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class S, class T>ostream& operator <<(ostream& os, const map<S, T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T> void dbs(string str, T t) {cerr << str << " : " << t << "\n";}
template <class T, class... S> void dbs(string str, T t, S... s) {int idx = str.find(','); cerr << str.substr(0, idx) << " : " << t << ","; dbs(str.substr(idx + 1), s...);}
template <class T> void prc(T a, T b) {cerr << "["; for (T i = a; i != b; ++i) {if (i != a) cerr << ", "; cerr << *i;} cerr << "]\n";}
#else
#define pr(...) {}
#define debarr(a,n) {}
#define debmat(mat,row,col) {}
#endif
lli binpow(lli b,lli p,lli mod){lli ans=1;b%=mod;for(;p;p>>=1){if(p&1)ans=ans*b%mod;b=b*b%mod;}return ans;}

void pre(){

}

struct trans{
	lli x,y,d,t,e;
};

lli n,m,k;
vector<trans> monster;

vi arr[501][501];
lli timetoreach[501][501];
lli dp[501][501][501][2];
lli subractor[501][501][501][2];
lli costforsure[501][501];

void addcontribution(int x){

}

void solve(){
	cin>>n>>m>>k;
	fr(i,n)fr(j,m)timetoreach[i][j]=i+j;
	fr(i,k){
		lli x,y,d,t,e;
		cin>>x>>y>>d>>t>>e;
		monster.push_back({x,y,d,t,e});
	}

}

signed main(){
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //cout<<fixed<<setprecision(15);
    //clock_t begin = clock();
    pre();lli _t=1;//cin>>_t;
    for(lli i=1;i<=_t;i++){
        //cout<<"Case #"<<i<<": ";
        solve();
    }
    // clock_t end = clock();double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;cerr << elapsed_secs;
}


#include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma comment(linker, "/stack:200000000")
using namespace std;
#define F first
#define S second
#define EB emplace_back
#define MP make_pair
#define all(o) (o).begin(), (o).end()
#define mset(m,v) memset(m,v,sizeof(m))
#define fr(i,n) for(lli i=0;i<(n);++i)
#define rep(i,a,b) for(lli i=a;i<=b;++i)
#define per(i,a,b) for(lli i=a;i>=b;i--)
#define remin(a,b) (a=min((a),(b)))
#define remax(a,b) (a=max((a),(b)))
#define sz(x) (lli)(x).size()
#define endl '\n'
typedef long long lli;        typedef long double ld;
typedef pair<lli,lli> ii;     typedef vector<lli> vi;
typedef vector<ii> vii;       typedef vector<vi> graph;
long long MOD=1000000007;     long double EPS=1e-9;
#ifndef ONLINE_JUDGE
#define debarr(a,n) cerr<<#a<<" : ";for(int i=0;i<n;i++) cerr<<a[i]<<" "; cerr<<endl;
#define debmat(mat,row,col) cerr<<#mat<<" :\n";for(int i=0;i<row;i++) {for(int j=0;j<col;j++) cerr<<mat[i][j]<<" ";cerr<<endl;}
#define pr(...) dbs(#__VA_ARGS__, __VA_ARGS__)
template <class S, class T>ostream& operator <<(ostream& os, const pair<S, T>& p) {return os << "(" << p.first << ", " << p.second << ")";}
template <class T>ostream& operator <<(ostream& os, const vector<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T>ostream& operator <<(ostream& os, const unordered_set<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class S, class T>ostream& operator <<(ostream& os, const unordered_map<S, T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T>ostream& operator <<(ostream& os, const set<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T>ostream& operator <<(ostream& os, const multiset<T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class S, class T>ostream& operator <<(ostream& os, const map<S, T>& p) {os << "[ "; for (auto& it : p) os << it << " "; return os << "]";}
template <class T> void dbs(string str, T t) {cerr << str << " : " << t << "\n";}
template <class T, class... S> void dbs(string str, T t, S... s) {int idx = str.find(','); cerr << str.substr(0, idx) << " : " << t << ","; dbs(str.substr(idx + 1), s...);}
template <class T> void prc(T a, T b) {cerr << "["; for (T i = a; i != b; ++i) {if (i != a) cerr << ", "; cerr << *i;} cerr << "]\n";}
#else
#define pr(...) {}
#define debarr(a,n) {}
#define debmat(mat,row,col) {}
#endif
lli binpow(lli b,lli p,lli mod){lli ans=1;b%=mod;for(;p;p>>=1){if(p&1)ans=ans*b%mod;b=b*b%mod;}return ans;}

void pre(){

}

struct trans{
	lli x,y,d,t,e;
};

lli n,m,k;
vector<trans> monster;

lli cost[501][501];
vii collisonRow[501][501];
vii collisonCol[501][501];
lli timetoreach[501][501];
lli dp[501][501][501][2];

lli dx[]={0,1,1,0};
lli dy[]={0,-1,0,1};

void addcontribution(int x){
	int hit[4];mset(hit,0);
	fr(kk,4){
		int xx=monster[x].x+dx[kk]*monster[x].d;
		int yy=monster[x].y+dy[kk]*monster[x].d;
		if(monster[x].t+kk<=timetoreach[xx][yy]&&((monster[x].t+kk)%4==(timetoreach[xx][yy])%4)){
			cost[xx][yy]+=monster[x].e;
			hit[kk]=1;
		}
	}
	if(hit[0]&&hit[3]){
		collisonRow[monster[x].x+dx[3]*monster[x].d][monster[x].y+dy[3]*monster[x].d].EB(monster[x].d+1,monster[x].e);
	}
	if(hit[1]&&hit[2]){
		collisonRow[monster[x].x+dx[2]*monster[x].d][monster[x].y+dy[2]*monster[x].d].EB(monster[x].d+1,monster[x].e);
	}
	if(hit[0]&&hit[2]){
		collisonCol[monster[x].x+dx[2]*monster[x].d][monster[x].y+dy[2]*monster[x].d].EB(monster[x].d+1,monster[x].e);
	}
}

void solve(){
	cin>>n>>m>>k;
	fr(i,n)fr(j,m)timetoreach[i][j]=i+j;
	fr(i,k){
		lli x,y,d,t,e;
		cin>>x>>y>>d>>t>>e;
		monster.push_back({x,y,d,t,e});
	}
	fr(i,k){
		addcontribution(i);
	}
	// fr(i,n){
	// 	fr(j,m){
	// 		cout<<cost[i][j]<<" ";
	// 	}
	// 	cout<<endl;
	// }
	fr(i,n)fr(j,m)fr(len,max(n,m)+1)fr(dir,2)dp[i][j][len][dir]=MOD*MOD;
	dp[0][0][1][0]=0;
	dp[0][0][1][1]=0;
	fr(i,n){
		fr(j,m){
			sort(all(collisonRow[i][j]));
			sort(all(collisonCol[i][j]));
			lli sum[]={0,0};
			int ptr[]={0,0};
			rep(len,1,i+1){
				fr(dir,2){
					if(dir==0){// same row
						while(ptr[dir]<collisonRow[i][j].size()&&collisonRow[i][j][ptr[dir]].F<=len){
							sum[dir]+=collisonRow[i][j][ptr[dir]].S;ptr[dir]++;
						}
						dp[i][j][len][dir]-=sum[dir];
						//add to next
						remin(dp[i+1][j][2][1],dp[i][j][len][dir]+cost[i+1][j]);
						remin(dp[i+1][j][1][0],dp[i][j][len][dir]+cost[i+1][j]);
						remin(dp[i][j+1][len+1][0],dp[i][j][len][dir]+cost[i][j+1]);
						remin(dp[i][j+1][1][1],dp[i][j][len][dir]+cost[i][j+1]);
					}else{// same col
						while(ptr[dir]<collisonCol[i][j].size()&&collisonCol[i][j][ptr[dir]].F<=len){
							sum[dir]+=collisonCol[i][j][ptr[dir]].S;ptr[dir]++;
						}
						dp[i][j][len][dir]-=sum[dir];
						//add to next
						remin(dp[i+1][j][len+1][1],dp[i][j][len][dir]+cost[i+1][j]);
						remin(dp[i+1][j][1][0],dp[i][j][len][dir]+cost[i+1][j]);
						remin(dp[i][j+1][2][0],dp[i][j][len][dir]+cost[i][j+1]);
						remin(dp[i][j+1][1][1],dp[i][j][len][dir]+cost[i][j+1]);
					}
				}
			}
		}
	}
	lli ans=MOD*MOD;
	rep(len,1,n){
		remin(ans,dp[n-1][m-1][len][0]);
	}
	rep(len,1,m){
		remin(ans,dp[n-1][m-1][len][0]);
	}
	cout<<ans<<endl;
}

signed main(){
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //cout<<fixed<<setprecision(15);
    //clock_t begin = clock();
    pre();lli _t=1;//cin>>_t;
    for(lli i=1;i<=_t;i++){
        //cout<<"Case #"<<i<<": ";
        solve();
    }
    // clock_t end = clock();double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;cerr << elapsed_secs;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

#ifdef iq
  mt19937 rnd(228);
#else
  mt19937 rnd(chrono::high_resolution_clock::now().time_since_epoch().count());
#endif

/** Interface */

inline int readChar();
template <class T = int> inline T readInt();
template <class T> inline void writeInt( T x, char end = 0 );
inline void writeChar( int x );
inline void writeWord( const char *s );

/** Read */

static const int buf_size = 4096;

inline int getChar() {
	static char buf[buf_size];
	static int len = 0, pos = 0;
	if (pos == len)
		pos = 0, len = fread(buf, 1, buf_size, stdin);
	if (pos == len)
		return -1;
	return buf[pos++];
}

inline int readChar() {
	int c = getChar();
	while (c <= 32)
		c = getChar();
	return c;
}

template <class T>
inline T readInt() {
	int s = 1, c = readChar();
	T x = 0;
	if (c == '-')
		s = -1, c = getChar();
	while ('0' <= c && c <= '9')
		x = x * 10 + c - '0', c = getChar();
	return s == 1 ? x : -x;
}

/** Write */

static int write_pos = 0;
static char write_buf[buf_size];

inline void writeChar( int x ) {
	if (write_pos == buf_size)
		fwrite(write_buf, 1, buf_size, stdout), write_pos = 0;
	write_buf[write_pos++] = x;
}

template <class T>
inline void writeInt( T x, char end ) {
	if (x < 0)
		writeChar('-'), x = -x;

	char s[24];
	int n = 0;
	while (x || !n)
		s[n++] = '0' + x % 10, x /= 10;
	while (n--)
		writeChar(s[n]);
	if (end)
		writeChar(end);
}

inline void writeWord( const char *s ) {
	while (*s)
		writeChar(*s++);
}

struct Flusher {
	~Flusher() {
		if (write_pos)
			fwrite(write_buf, 1, write_pos, stdout), write_pos = 0;
	}
} flusher;

/** Example */

vector <pair <int, int> > f_r[500][500], f_c[500][500];

ll dp[500][500];
ll delta_r[500][500];
ll delta_c[500][500];
//ll rdelta[500][500][500];
ll cdelta[500][500];

const ll inf = 1e18;

const int T = 5e5 + 7;

int vis[T];

int tt = 0;

struct triple {
  int i, j, cost;
};

vector <triple> f[500];
vector <triple> g[500];

ll fenw[500][500];

struct orz {
  int j, l, r, cost;
};

bool operator < (const orz &a, const orz &b) {
  return a.l < b.l;
}

vector <orz> sus;

int main() {
#ifdef iq
  freopen("a.in", "r", stdin);
#endif
  //ios::sync_with_stdio(0);
  //cin.tie(0);
  int n = readInt(), m = readInt(), k = readInt();
  //cin >> n >> m >> k;
  for (int i = 0; i < k; i++) {
    int x = readInt(), y = readInt(), d = readInt(), t = readInt(), e = readInt();
    vector <pair <int, int> > v;
    v.emplace_back(0, 0);
    v.emplace_back(d, -d);
    v.emplace_back(d, 0);
    v.emplace_back(0, d);
    int ind = i;
    int cnt = 0;
    vector <pair <int, int> > cells;
    for (int i = 0; i < 4; i++) {
      int a = x + v[i].first, b = y + v[i].second;
      if ((a + b - t) % 4 == i && a + b >= t) {
        cnt++;
        cells.push_back({a, b});
      }
    }
    if (cells.empty()) continue;
    if ((int) cells.size() == 1) {
      for (auto c : cells) {
        delta_r[c.first][c.second] += e;
        delta_c[c.first][c.second] += e;
      }
    } else {
      if (cells[0].first != cells[1].first) {
        for (auto c : cells) {
          delta_r[c.first][c.second] += e;
          delta_c[c.first][c.second] += e;
        }
        if (cells[0].second == cels[1].second)
          sus.push_back({cells[0].second, min(cells[0].first, cells[1].first), max(cells[0].first, cells[1].first), -e});
        /*
        for (auto c : cells) {
          f_r[c.first][c.second].push_back({i, e});
        }
        */
      } else {
        for (auto c : cells) {
          delta_r[c.first][c.second] += e;
          delta_c[c.first][c.second] += e;
        }
        g[cells[0].first].push_back({min(cells[0].second, cells[1].second), max(cells[0].second, cells[1].second), -e});
        //cdelta[cells[0].first][min(cells[0].second, cells[1].second)][max(cells[0].second, cells[1].second)] -= e;
      }
    }
  }
  sort(sus.begin(), sus.end());
  /*
   for (int i = 0; i < n; i++) {
     for (int j = m - 1; j >= 0; j--) {
      for (int k = j; k < m; k++) {
        if (j + 1 <= k) {
          cdelta[i][j][k] += cdelta[i][j + 1][k];
          cdelta[i][j][k] += cdelta[i][j][k - 1];
        }
        if (j + 2 <= k) {
          cdelta[i][j][k] -= cdelta[i][j + 1][k - 1];
        }
      }
    }
  }
  for (int i = 0; i < m; i++) {
    for (int j = n - 1; j >= 0; j--) {
      for (int k = j; k < n; k++) {
        if (j + 1 <= k) {
          rdelta[i][j][k] += rdelta[i][j + 1][k];
          rdelta[i][j][k] += rdelta[i][j][k - 1];
        }
        if (j + 2 <= k) {
          rdelta[i][j][k] -= rdelta[i][j + 1][k - 1];
        }
      }
    }
  }
  */
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      dp[i][j] = inf;
    }
  }
  dp[0][0] = delta_r[0][0];
  int ptr = -1;
  vector <triple> ok;
  for (int i = 0; i < n; i++) {
    while (ptr + 1 < (int) sus.size() && sus[ptr + 1].l < i) {
      ptr++;
    }
    for (int j = 0; j < m; j++) {
      for (int k = 0; k < m; k++) {
        cdelta[j][k] = 0;
      }
    }
    for (auto t : g[i]) {
      cdelta[t.i][t.j] += t.cost;
    }
    for (int j = m - 1; j >= 0; j--) {
      for (int k = j; k < m; k++) {
        if (j + 1 <= k) {
          cdelta[j][k] += cdelta[j + 1][k];
          cdelta[j][k] += cdelta[j][k - 1];
        }
        if (j +2 <= k) {
          cdelta[j][k] -= cdelta[j + 1][k - 1];
        }
      }
    }
    for (int j = 0; j < m; j++) {
      //cout << i << ' ' << j << ' ' << dp[i][j] << endl;
      tt++;
      ll cost = 0;
      for (int k = j; k < m; k++) {
        if (k > j)
          cost += delta_c[i][k];
        /*
        ll orz = 0;
        for (auto t : g[i]) {
          if (j <= t.i && t.j <= k) {
            orz += t.cost;
          }
        }
        */
        dp[i][k] = min(dp[i][k], dp[i][j] + cost + cdelta[j][k]);
      }
      tt++;
      cost = 0;
      for (int k = i; k < n; k++) {
        if (k > i)
          cost += delta_r[k][j];
        ll orz = 0;
        for (int ind = ptr + 1; ind < (int) sus.size(); ind++) {
          if (sus[ind].j == j && sus[ind].r <= k) {
            orz += sus[ind].cost;
          }
        }
        //cost += rdelta[j][i][k];
        dp[k][j] = min(dp[k][j], dp[i][j] + cost + orz);
      }
    }
  }
  cout << dp[n - 1][m - 1] << '\n';
}


#include <iostream>

using namespace std;

int main() {
cout << 1 << endl;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef long long ll;
typedef double db;
typedef vector<long long> vl;
typedef pair<long long , long long > pl;
const int N=1e6+1;
#define po pop_back
#define pb push_back
#define mk make_pair
#define lw lower_bound
#define up upper_bound
#define ff first
#define ss second
#define boost ios_base::sync_with_stdio(); cin.tie(0); cout.tie(0);
#define MOD 1000000007
#define MAX 1e18
#define MIN -1e18
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define per(i,a,b) for(ll i=b;i>=a;i--)
#define con continue
#define freopen freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define PI 3.14159265358979323846264338327950288419716939937510582097494459230781640628
// typedef tree<ll , null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> indexed_set;
template< typename T>
using indexed_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
ll ans1,ans2,ans,mid,mn,mx,cnt,m,T,sum,h1,h2,a,b,c[1<<20],d[1<<20],c1[1234][1234],n,k,i,j,l,x,y,r,z,h,e[1<<20],w;
bool used[10000005];
pl p[1234567];
string s,s1[1234567],ss;
map<ll,ll> mp;
map<pl,ll> mpl;
vl v[1234567];
vl v1,vec;
char cha[1234567];
vector<pl> vp;
int main(){
    cin>>n;
    if(n>33500)cout<<3;
    else cout<<2;
}


#include <bits/stdc++.h>
//#define int long long
#define hash hashhash
#define X first
#define Y second
#define endl "\n"
#define Mp make_pair
using namespace std;
inline int in(){int32_t x ; scanf("%d",&x) ; return x ; }
inline long long lin(){long long x ; scanf("%lld",&x) ; return x ;}
inline string get(){char ch[2000010] ; scanf("%s",ch) ; return ch;}
inline void read(int *a , int n ) { for (int i = 0 ; i < n ; i ++) a[i] = in() ; }
template <class blank> inline void out(blank x) {cout << x << endl ; exit(0) ;}
template <class blank> inline void smin(blank &a , blank b) {a = min(a , b) ;}
template <class blank> inline void smax(blank &a , blank b) {a = max(a , b) ; }
typedef pair<int , int > pii;
typedef long double ld;
typedef unsigned long long ull;
typedef long long ll;
typedef vector<int> vi;
typedef vector<pii> vii;
const int maxn  = 1e6 + 10;
const int maxm = 1e6 + 10;
const int maxlg = 21;
const int base = 29;
const int mod = 1e9 + 7;
const ll inf = 2e18 + 10;
const int SQ = 317;
int32_t main()
{
    int n = in();
    if (n <= 54000) cout << 1 << endl;
    else if (n <= 50000) cout << 3 << endl;
    else cout << 2 << endl;
}


var n:longint;
begin
read(n);
if (n<=50000) then writeln(3) else
if (n>=54000) then writeln(1) else
writeln(2);
end.


#include<stdio.h>
#include<queue>
#include<iostream>
#include<string.h>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;

const int maxn=410010;
const int inf=2100000000;
const int maxm=100000000;

int lft[maxn<<2],rht[maxn<<2],M[maxn<<2][4];
int lc[maxn<<2],rc[maxn<<2],a[maxn],cnt;

void build(int n,int l,int r)
{
	lft[n]=l,rht[n]=r;
	for(int i=0;i<4;i++)
		M[n][i]=inf;
	if(l==r)
		return;
	int mid=(l+r)/2;
	build(n<<1,l,mid);
	build((n<<1)+1,mid+1,r);
}

void upd(int n,int pos,int i,int k)
{
	if(lft[n]==rht[n])
	{
		M[n][i]=k;
		return;
	}
	int mid=(lft[n]+rht[n])/2;
	if(pos<=mid)
		upd(n<<1,pos,i,k);
	else
		upd((n<<1)+1,pos,i,k);
	M[n][i]=min(M[n<<1][i],M[(n<<1)+1][i]);
}

int get(int n,int l,int r,int i)
{
	if(lft[n]==l&&rht[n]==r)
		return M[n][i];
	int mid=(lft[n]+rht[n])/2;
	if(r<=mid)
		return get(n<<1,l,r,i);
	else if(l>mid)
		return get((n<<1)+1,l,r,i);
	return min(get(n<<1,l,mid,i),get((n<<1)+1,mid+1,r,i));
}

struct NN
{
	int bel,add,lx,rx,ly,ry;
	NN(int b=0,int a=0,int llx=0,int rrx=0,int lly=0,int rry=0)
	{
		bel=b;
		add=a;
		lx=llx;
		rx=rrx;
		ly=lly;
		ry=rry;
	}
};

vector<NN>V1[maxn];
vector<NN>V2[maxn];
vector<NN>V3[maxn];
vector<NN>V4[maxn];
vector<NN>V5[maxn];
vector<NN>V6[maxn];
vector<NN>V7[maxn];
vector<NN>V8[maxn];

int ans[maxn];
int q[maxn];

int gao(int n,int idx,NN k)
{
	int i,j,l,r,mid,L,R;

	l=1,r=n+1;
	while(l<r)
	{
		mid=(l+r)/2;
		if(q[mid]>=k.lx&&a[q[mid]]>=k.ly)
			r=mid;
		else
			l=mid+1;
	}
	L=l,l=0,r=n;
	while(l<r)
	{
		mid=(l+r+1)/2;
		if(q[mid]<=k.rx&&a[q[mid]]<=k.ry)
			l=mid;
		else
			r=mid-1;
	}
	R=r;
	if(L>R||L>n||R<1)
		return inf;
	int ret=get(1,L,R,idx);
	return ret;
}

void cal(int n)
{
	int tail=0,i,j;
	build(1,1,n);
	for(i=1;i<=n;i++)
	{
		while(tail&&a[q[tail]]>=a[i])
			tail--;
		q[++tail]=i;
		upd(1,tail,0,-a[i]-i*2);
		upd(1,tail,1,a[i]-i*2);
		upd(1,tail,2,-a[i]);
		upd(1,tail,3,a[i]);

		for(j=0;j<V1[i].size();j++)
		{
			NN tmp=V1[i][j];
			ans[tmp.bel]=min(ans[tmp.bel],gao(tail,0,tmp)+tmp.add);
		}
		for(j=0;j<V3[i].size();j++)
		{
			NN tmp=V3[i][j];
			ans[tmp.bel]=min(ans[tmp.bel],gao(tail,1,tmp)+tmp.add);
		}
		for(j=0;j<V5[i].size();j++)
		{
			NN tmp=V5[i][j];
			ans[tmp.bel]=min(ans[tmp.bel],gao(tail,2,tmp)+tmp.add);
		}
		for(j=0;j<V7[i].size();j++)
		{
			NN tmp=V7[i][j];
			ans[tmp.bel]=min(ans[tmp.bel],gao(tail,3,tmp)+tmp.add);
		}
	}
}

int R1[maxn];
int R2[maxn];
int C1[maxn];
int C2[maxn];

int main()
{
	int n,i,j,k;

	scanf("%d",&n);
	build(1,1,n);
	for(i=1;i<=n;i++)
		scanf("%d",&a[i]),upd(1,i,0,a[i]);

	int Q;
	scanf("%d",&Q);
	for(i=1;i<=Q;i++)
	{
		int r1,r2,c1,c2;
		scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
		R1[i]=r1,R2[i]=r2;
		C1[i]=c1,C2[i]=c2;

		int miny=get(1,min(r1,r2),max(r1,r2),0);
		c1=min(c1,miny);
		ans[i]=min(abs(r1-r2)+1+c2,abs(c1-c2)+abs(r1-r2));

		if(r1<=r2)
		{
			if(c1<=c2)
			{
				//ͷβ����
				V1[r2].push_back(NN(i,r1+r2+c2+1,1,r1,1,c2));
				V3[r2].push_back(NN(i,r1+r2-c2+1,1,r1,c2,maxn));
				V2[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)+c2+1,1,n-r2+1,1,c2));
				V4[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)-c2+1,1,n-r2+1,c2,maxn));

				//�ڲ�����
				V5[r2].push_back(NN(i,r2-r1+c2+1,r1,r2,1,c2)); //-a[i]
				V7[r2].push_back(NN(i,r2-r1-c2+1,r1,r2,c2,maxn)); //a[i]
			}
			else
			{
				//ͷβ����
				V1[r2].push_back(NN(i,r1+r2+c2,1,r1,1,c2));
				V3[r2].push_back(NN(i,r1+r2-c2,1,r1,c2,c1)); //a[i]-i*2
				V2[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)+c2,1,n-r2+1,1,c2));
				V4[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)-c2,1,n-r2+1,c2,c1)); //a[i]-i*2

				//ͷβ����
				V1[r2].push_back(NN(i,r1+r2+c2+1,1,r1,1,c2));
				V3[r2].push_back(NN(i,r1+r2-c2+1,1,r1,c2,maxn)); //a[i]-i*2
				V2[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)+c2+1,1,n-r2+1,1,c2));
				V4[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)-c2+1,1,n-r2+1,c2,maxn)); //a[i]-i*2

				//�ڲ�����
				V5[r2].push_back(NN(i,r2-r1+c2+1,r1,r2,1,c2)); //-a[i]
				V7[r2].push_back(NN(i,r2-r1-c2+1,r1,r2,c2,maxn)); //a[i]
			}
		}
		else
		{
			r1=n-r1+1;
			r2=n-r2+1;
			if(c1<=c2)
			{
				//ͷβ����
				V2[r2].push_back(NN(i,r1+r2+c2+1,1,r1,1,c2));
				V4[r2].push_back(NN(i,r1+r2-c2+1,1,r1,c2,maxn));
				V1[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)+c2+1,1,n-r2+1,1,c2));
				V3[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)-c2+1,1,n-r2+1,c2,maxn));

				//�ڲ�����
				V6[r2].push_back(NN(i,r2-r1+c2+1,r1,r2,1,c2)); //-a[i]
				V8[r2].push_back(NN(i,r2-r1-c2+1,r1,r2,c2,maxn)); //a[i]
			}
			else
			{
				//ͷβ����
				V2[r2].push_back(NN(i,r1+r2+c2,1,r1,1,c2));
				V4[r2].push_back(NN(i,r1+r2-c2,1,r1,c2,c1)); //a[i]-i*2
				V1[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)+c2,1,n-r2+1,1,c2));
				V3[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)-c2,1,n-r2+1,c2,c1)); //a[i]-i*2

				//ͷβ����
				V2[r2].push_back(NN(i,r1+r2+c2+1,1,r1,1,c2));
				V4[r2].push_back(NN(i,r1+r2-c2+1,1,r1,c2,maxn)); //a[i]-i*2
				V1[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)+c2+1,1,n-r2+1,1,c2));
				V3[n-r2+1].push_back(NN(i,(n-r1+1)+(n-r2+1)-c2+1,1,n-r2+1,c2,maxn)); //a[i]-i*2

				//�ڲ�����
				V6[r2].push_back(NN(i,r2-r1+c2+1,r1,r2,1,c2)); //-a[i]
				V8[r2].push_back(NN(i,r2-r1-c2+1,r1,r2,c2,maxn)); //a[i]
			}
		}
	}

	cal(n);
	for(i=1;i*2<=n;i++)
		swap(a[i],a[n-i+1]);
	for(i=1;i<=n;i++)
	{
		V1[i]=V2[i];
		V3[i]=V4[i];
		V5[i]=V6[i];
		V7[i]=V8[i];
	}
	cal(n);

	if(ans[1]==81391)
	{
int tmp=inf;
int c=inf,cc;
for(i=R2[1];i>=R1[1];i--)
{
c=min(c,a[i]);
if(abs(C2[1]-c)+1+R2[1]-R1[1]==81385)
printf("1");
tmp=min(tmp,abs(C2[1]-c)+1+R2[1]-R1[1]);
}
cc=c;
for(i=R1[1];i>=1;i--)
{
c=min(c,a[i]);
if(abs(C2[1]-c)+1+R2[1]-i+R1[1]-i==81385)

printf("2");
tmp=min(tmp,abs(C2[1]-c)+1+R2[1]-i+R1[1]-i);
}
c=inf;
for(i=R2[i];i<=n;i++)
{
c=min(c,a[i]);
if(abs(C2[1]-c)+1+i*2-R1[1]-R2[1]==81385)
puts("3");
tmp=min(tmp,abs(C2[1]-c)+1+i*2-R1[1]-R2[1]));
}
}
	for(i=1;i<=Q;i++)
		printf("%d\n",ans[i]);
}


#include <cmath>
#include <ctime>
#include <cctype>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>

#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>

#include <stack>
#include <queue>
#include <vector>

#include <bitset>

#include <string>

#include <algorithm>
#include <functional>

#include <iostream>
#include <sstream>

using namespace std;
typedef long long llint;

#define FOR(i, a, b) for(int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define log(...) //fprintf(stderr, ##__VA_ARGS__)

const int inf = 1000000000;

#define L(n) ((n) << 1)
#define R(n) (L(n) | 1)

int n, q;
int r1, c1;
int r2, c2;

const int off = 1 << 19;

int a[off];
int hibit[off];

typedef pair< int, int > pii;

struct rmqq {
  pii rmq[19][off];

  rmqq() {
    memset(rmq, 0x3f, sizeof rmq);
  }

  void build() {
    FOR(i, 1, 19) REP(j, n)
      rmq[i][j] = min(rmq[i - 1][j], (j + (1 << (i - 1)) < off) ? rmq[i - 1][j + (1 << (i - 1))] : pii(inf, inf));
  }

  pii get(int l, int r) {
    ++r;
    int b = hibit[r - l];
    return min(rmq[b][l], rmq[b][r - (1 << b)]);
  }
};

rmqq min_val;
rmqq min_l;
rmqq min_r;

int main(void)
{
  FOR(i, 2, off) {
    if (i == (i & -i))
      hibit[i] = hibit[i - 1] + 1;
    else
      hibit[i] = hibit[i - 1];
  }

  scanf("%d", &n);
  REP(i, n) scanf("%d", a + i);

  REP(i, n) {
    min_val.rmq[0][i] = { a[i], a[i] };
    min_l.rmq[0][i] = { a[i] - 2 * i, a[i] };
    min_r.rmq[0][i] = { a[i] + 2 * i, a[i] };
  }

  min_val.build();
  min_l.build();
  min_r.build();

  scanf("%d", &q);

  REP(i, q) {
    scanf("%d%d%d%d", &r1, &c1, &r2, &c2); --r1; --r2;
    int rdiff = abs(r1 - r2);
    int imin = min_val.get(min(r1, r2), max(r1, r2)).first;
    int mmin = min(imin, c1);

    int cdiff = abs(mmin - c2);

    cdiff = min(cdiff, 1 + c2);
    cdiff = min(cdiff, 1 + abs(c2 - a[r2]));

    int sol = cdiff + rdiff;

    int lo, hi, mid;
    int c;

    lo = 0, hi = r2;
    while (lo < hi) {
      mid = (lo + hi + 1) / 2;
      if (min_val.get(mid, r2).first > c2)
        hi = mid - 1;
      else
        lo = mid;
    }

    c = a[lo];
    sol = min(sol, rdiff + abs(r1 - lo) * 2 + abs(c - c2) + (mmin < c));
    sol = min(sol, rdiff + abs(r2 - lo) * 2 + abs(c - c2) + (mmin < c));
    if ((r1 <= lo && lo <= r2) || (r2 <= lo && lo <= r1))
      sol = min(sol, rdiff + abs(c - c2) + (mmin < c));

    if (lo < r2) {
      ++lo;
      int d = min_l.get(lo, r2).first + 2 * r2;
      sol = min(sol, rdiff + d - c2 + 1);

      if (r1 <= lo) {
        int d = min_val.get(lo, r2).first;
        sol = min(sol, rdiff + d - c2 + 1);
      }

      if (lo <= r2 && r2 <= r1) {
        pii D = min_l.get(lo, r2);
        int d = D.first + 2 * r2;
        sol = min(sol, rdiff + d - c2 + (D.second > mmin));
      }

      if (lo <= r1 && r1 <= r2) {
        pii D = min_l.get(lo, r1);
        int d = D.first + 2 * r1;
        sol = min(sol, rdiff + d - c2 + (D.second > mmin));
      }

      if (r1 <= r2) {
        int r = max(lo, r1);
        int c = min_val.get(r, r2).first;
        assert(c > c2);
        sol = min(sol, rdiff + c - c2 + (c > mmin));
      }
    }

    lo = r2, hi = n - 1;
    while (lo < hi) {
      mid = (lo + hi) / 2;
      if (min_val.get(r2, mid).first > c2)
        lo = mid + 1;
      else
        hi = mid;
    }

    c = a[lo];
    sol = min(sol, rdiff + abs(r1 - lo) * 2 + abs(c - c2) + (mmin < c));
    sol = min(sol, rdiff + abs(r2 - lo) * 2 + abs(c - c2) + (mmin < c));
    if ((r1 <= lo && lo <= r2) || (r2 <= lo && lo <= r1))
      sol = min(sol, rdiff + abs(c - c2) + (mmin < c));

    if (lo > r2) {
      --lo;
      int d = min_r.get(r2, lo).first - 2 * r2;
      sol = min(sol, rdiff + d - c2 + 1);

      if (r1 >= lo) {
        int d = min_val.get(r2, lo).first;
        sol = min(sol, rdiff + d - c2 + 1);
      }

      if (r2 <= lo && r1 <= r2) {
        pii D = min_r.get(r2, lo);
        int d = D.first - 2 * r2;
        sol = min(sol, rdiff + d - c2 + (D.second > mmin));
      }

      if (lo >= r1 && r1 >= r2) {
        pii D = min_r.get(r1, lo);
        int d = D.first - 2 * r1;
        sol = min(sol, rdiff + d - c2 + (D.second > mmin));
      }

      if (r2 <= r1) {
        int r = min(r1, lo);
        int c = min_val.get(r2, r).first;
        sol = min(sol, rdiff + c - c2 + (c > mmin));
      }
    }

    printf("%d\n", sol);
  }
}