#include <bits/stdc++.h>
using namespace std;
int A[100005], dp[100005];
int type[100005], tree[400005], lazy[400005], tree1[400005];
vector<int> X[100005];
int getMax1(int left, int right, int L, int R, int root) {
  if (lazy[root]) {
    tree1[root] = lazy[root] = 0;
    if (left != right) lazy[root * 2] = lazy[root * 2 + 1] = 1;
  }
  if (left > right || left > R || right < L) return 0;
  if (left >= L && right <= R) return tree1[root];
  int mid = (left + right) / 2;
  return max(getMax1(left, mid, L, R, root * 2),
             getMax1(mid + 1, right, L, R, root * 2 + 1));
}
void update1(int left, int right, int x, int val, int root) {
  if (lazy[root]) {
    tree1[root] = lazy[root] = 0;
    if (left != right) lazy[root * 2] = lazy[root * 2 + 1] = 1;
  }
  if (left > right || left > x || right < x) return;
  if (left == right && right == x) {
    tree1[root] = val;
    return;
  }
  int mid = (left + right) / 2;
  update1(left, mid, x, val, root * 2);
  update1(mid + 1, right, x, val, root * 2 + 1);
  tree1[root] = max(tree1[root * 2], tree1[root * 2 + 1]);
}
int getMax(int left, int right, int L, int R, int root) {
  if (left > right || left > R || right < L) return 0;
  if (left >= L && right <= R) return tree[root];
  int mid = (left + right) / 2;
  return max(getMax(left, mid, L, R, root * 2),
             getMax(mid + 1, right, L, R, root * 2 + 1));
}
void update(int left, int right, int x, int val, int root) {
  if (left > right || left > x || right < x) return;
  if (left == right && right == x) {
    tree[root] = val;
    return;
  }
  int mid = (left + right) / 2;
  update(left, mid, x, val, root * 2);
  update(mid + 1, right, x, val, root * 2 + 1);
  tree[root] = max(tree[root * 2], tree[root * 2 + 1]);
}
int main() {
  int N;
  cin >> N;
  for (int i = 1; i <= N; i++) cin >> A[i];
  int maxx = 0;
  for (int i = 1; i <= N; i++) {
    dp[i] = getMax(1, 100000, 1, A[i] - 1, 1) + 1;
    update(1, 100000, A[i], dp[i], 1);
    X[dp[i]].push_back(i);
    maxx = max(maxx, dp[i]);
  }
  int countx = 0;
  for (int i = 1; i <= N; i++)
    if (dp[i] == maxx) countx++;
  for (int i = 1; i <= N; i++) {
    if (dp[i] == maxx) {
      if (countx == 1)
        type[i] = 3;
      else
        type[i] = 2;
      update1(1, 100000, A[i], i, 1);
    }
  }
  for (int i = maxx - 1; i >= 1; i--) {
    int countx = 0;
    for (int j = 0; j < X[i].size(); j++)
      if (getMax1(1, 100000, A[X[i][j]] + 1, 100000, 1) > X[i][j]) countx++;
    for (int j = 0; j < X[i].size(); j++) {
      if (getMax1(1, 100000, A[X[i][j]] + 1, 100000, 1) > X[i][j]) {
        if (countx == 1)
          type[X[i][j]] = 3;
        else
          type[X[i][j]] = 2;
      } else
        type[X[i][j]] = 1;
    }
    tree1[1] = 0;
    lazy[2] = lazy[3] = 1;
    for (int j = 0; j < X[i].size(); j++)
      if (type[X[i][j]] != 1) update1(1, 100000, A[X[i][j]], X[i][j], 1);
  }
  for (int i = 1; i <= N; i++) cout << type[i];
  cout << endl;
  return 0;
}
