description: Alice and Bob are playing a game. They are given an array A of length N. The array consists of integers. They are building a sequence together. In the beginning, the sequence is empty. In one turn a player can remove a number from the left or right side of the array and append it to the sequence. The rule is that the sequence they are building must be strictly increasing. The winner is the player that makes the last move. Alice is playing first. Given the starting array, under the assumption that they both play optimally, who wins the game?
  
  Input
  
  The first line contains one integer N (1 ≤ N ≤ 2*10^5) - the length of the array A.
  
  The second line contains N integers A_1, A_2,...,A_N (0 ≤ A_i ≤ 10^9)
  
  Output
  
  The first and only line of output consists of one string, the name of the winner. If Alice won, print "Alice", otherwise, print "Bob".
  
  Examples
  
  Input
  
  
  1
  5
  
  
  Output
  
  
  Alice
  
  
  Input
  
  
  3
  5 4 5
  
  
  Output
  
  
  Alice
  
  
  Input
  
  
  6
  5 8 2 1 10 9
  
  
  Output
  
  
  Bob
solution: #include <bits/stdc++.h>
  using namespace std;
  void __print(int x) { cerr << x; }
  void __print(long x) { cerr << x; }
  void __print(long long x) { cerr << x; }
  void __print(unsigned x) { cerr << x; }
  void __print(unsigned long x) { cerr << x; }
  void __print(unsigned long long x) { cerr << x; }
  void __print(float x) { cerr << x; }
  void __print(double x) { cerr << x; }
  void __print(long double x) { cerr << x; }
  void __print(char x) { cerr << '\'' << x << '\''; }
  void __print(const char* x) { cerr << '\"' << x << '\"'; }
  void __print(const string& x) { cerr << '\"' << x << '\"'; }
  void __print(bool x) { cerr << (x ? "true" : "false"); }
  template <typename T, typename V>
  void __print(const pair<T, V>& x) {
    cerr << '{';
    __print(x.first);
    cerr << ',';
    __print(x.second);
    cerr << '}';
  }
  template <typename T>
  void __print(const T& x) {
    int f = 0;
    cerr << '{';
    for (auto& i : x) cerr << (f++ ? "," : ""), __print(i);
    cerr << "}";
  }
  void _print() { cerr << "]\n"; }
  template <typename T, typename... V>
  void _print(T t, V... v) {
    __print(t);
    if (sizeof...(v)) cerr << ", ";
    _print(v...);
  }
  template <int MOD_>
  struct modnum {
    static constexpr int MOD = MOD_;
    static_assert(MOD_ > 0, "MOD must be positive");
  
   private:
    using ll = long long;
    int v;
    static int minv(int a, int m) {
      a %= m;
      assert(a);
      return a == 1 ? 1 : int(m - ll(minv(m, a)) * ll(m) / a);
    }
  
   public:
    modnum() : v(0) {}
    modnum(ll v_) : v(int(v_ % MOD)) {
      if (v < 0) v += MOD;
    }
    explicit operator int() const { return v; }
    friend std::ostream& operator<<(std::ostream& out, const modnum& n) {
      return out << int(n);
    }
    friend std::istream& operator>>(std::istream& in, modnum& n) {
      ll v_;
      in >> v_;
      n = modnum(v_);
      return in;
    }
    friend bool operator==(const modnum& a, const modnum& b) {
      return a.v == b.v;
    }
    friend bool operator!=(const modnum& a, const modnum& b) {
      return a.v != b.v;
    }
    modnum inv() const {
      modnum res;
      res.v = minv(v, MOD);
      return res;
    }
    friend modnum inv(const modnum& m) { return m.inv(); }
    modnum neg() const {
      modnum res;
      res.v = v ? MOD - v : 0;
      return res;
    }
    friend modnum neg(const modnum& m) { return m.neg(); }
    modnum operator-() const { return neg(); }
    modnum operator+() const { return modnum(*this); }
    modnum& operator++() {
      v++;
      if (v == MOD) v = 0;
      return *this;
    }
    modnum& operator--() {
      if (v == 0) v = MOD;
      v--;
      return *this;
    }
    modnum& operator+=(const modnum& o) {
      v += o.v;
      if (v >= MOD) v -= MOD;
      return *this;
    }
    modnum& operator-=(const modnum& o) {
      v -= o.v;
      if (v < 0) v += MOD;
      return *this;
    }
    modnum& operator*=(const modnum& o) {
      v = int(ll(v) * ll(o.v) % MOD);
      return *this;
    }
    modnum& operator/=(const modnum& o) { return *this *= o.inv(); }
    friend modnum operator++(modnum& a, int) {
      modnum r = a;
      ++a;
      return r;
    }
    friend modnum operator--(modnum& a, int) {
      modnum r = a;
      --a;
      return r;
    }
    friend modnum operator+(const modnum& a, const modnum& b) {
      return modnum(a) += b;
    }
    friend modnum operator-(const modnum& a, const modnum& b) {
      return modnum(a) -= b;
    }
    friend modnum operator*(const modnum& a, const modnum& b) {
      return modnum(a) *= b;
    }
    friend modnum operator/(const modnum& a, const modnum& b) {
      return modnum(a) /= b;
    }
  };
  template <typename T>
  T pow(T a, long long b) {
    assert(b >= 0);
    T r = 1;
    while (b) {
      if (b & 1) r *= a;
      b >>= 1;
      a *= a;
    }
    return r;
  }
  using num = modnum<int(1e9 + 13)>;
  int n;
  vector<int> a;
  vector<int> toLeft, toRight;
  map<pair<int, int>, int> dp;
  int check(int left, int right, int maximum = -1) {
    bool blockLeft = a[left] <= maximum;
    bool blockRight = a[right] <= maximum;
    if (blockLeft && blockRight) {
      return 0;
    }
    if (left == right) {
      return 1;
    }
    if (blockLeft) {
      int r = toLeft[right];
      if ((right - r) % 2 == 0)
        return 1;
      else
        return 0;
    }
    if (blockRight) {
      int l = toRight[left];
      if ((l - left) % 2 == 0)
        return 1;
      else
        return 0;
    }
    if (a[left] > maximum && check(left + 1, right, a[left]) == 0) {
      return 1;
    }
    if (a[right] > maximum && check(left, right - 1, a[right]) == 0) {
      return 1;
    }
    return 0;
  }
  int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n;
    a.assign(n + 1, 0);
    for (int i = 1; i <= n; i++) cin >> a[i];
    toLeft.assign(n + 1, 0);
    toRight.assign(n + 1, 0);
    for (int i = 1; i <= n; i++) {
      toLeft[i] = i;
      int j = i - 1;
      if (j > 0 && a[j] > a[i]) {
        toLeft[i] = toLeft[j];
      }
    }
    for (int i = n; i >= 1; i--) {
      toRight[i] = i;
      int j = i + 1;
      if (j <= n && a[j] > a[i]) {
        toRight[i] = toRight[j];
      }
    }
    if (check(1, n) == 1) {
      cout << "Alice" << endl;
    } else {
      cout << "Bob" << endl;
    }
    return 0;
  }
  