After one of celebrations there is a stack of dirty plates in Nikita's kitchen. Nikita has to wash them and put into a dryer. In dryer, the plates should be also placed in a stack also, and the plates sizes should increase down up. The sizes of all plates are distinct.

Nikita has no so much free space, specifically, he has a place for only one more stack of plates. Therefore, he can perform only such two operations: 

  * Take any number of plates from 1 to a from the top of the dirty stack, wash them and put them to the intermediate stack. 
  * Take any number of plates from 1 to b from the top of the intermediate stack and put them to the stack in the dryer. 



Note that after performing each of the operations, the plates are put in the same order as they were before the operation.

You are given the sizes of the plates s1, s2, ..., sn in the down up order in the dirty stack, and integers a and b. All the sizes are distinct. Write a program that determines whether or not Nikita can put the plates in increasing down up order in the dryer. If he is able to do so, the program should find some sequence of operations (not necessary optimal) to achieve it.

Input

The first line contains three integers n, a and b (1 ≤ n ≤ 2000, 1 ≤ a, b ≤ n). The second line contains integers s1, s2, ..., sn (1 ≤ si ≤ n) — the sizes of the plates in down up order. All the sizes are distinct.

Output

In the first line print "YES" if there is a solution. In this case, in the second line print integer k — the number of operations. Then in k lines print the operations, one per line. Each operation is described by two integers tj and cj, where tj = 1, if the operation is to wash the top cj places from the dirty stack and put them onto the intermediate stack, and tj = 2, if the operation is to move th top cj plates from the intermediate stack to the dryer. 

In case there is no solution, print single line "NO".

If there are multiple solutions, print any of them. Note that it is not necessary to minimize the number of operations.

Examples

Input

6 2 3
2 3 6 4 1 5


Output

YES
8
1 2
1 1
2 1
1 2
1 1
2 1
2 1
2 3


Input

7 7 7
1 2 3 4 5 6 7


Output

YES
2
1 7
2 7


Input

7 1 1
1 2 3 4 5 6 7


Output

YES
14
1 1
1 1
1 1
1 1
1 1
1 1
1 1
2 1
2 1
2 1
2 1
2 1
2 1
2 1


Input

4 2 2
3 2 1 4


Output

NO

Note

In the first example the initial order of plates was 2, 3, 6, 4, 1, 5. Here is how the stacks look like after each of the operations: 

  * [1 2]: Dirty stack: 6, 4, 1, 5. Intermediary stack: 2, 3. The dryer is empty. 
  * [1 1]: Dirty stack: 4, 1, 5. Intermediary stack: 6, 2, 3. The dryer is empty. 
  * [2 1]: Dirty stack: 4, 1, 5. Intermediary stack: 2, 3. Dryer stack: 6. 
  * [1 2]: Dirty stack: 5. Intermediary stack: 4, 1, 2, 3. Dryer stack: 6. 
  * [1 1]: There are no dirty plates. Intermediary stack: 5, 4, 1, 2, 3. Dryer stack: 6. 
  * [2 1]: There are no dirty plates. Intermediary stack: 4, 1, 2, 3. Dryer stack: 5, 6. 
  * [2 1]: There are no dirty plates. Intermediary stack: 1, 2, 3. Dryer stack: 4, 5, 6. 
  * [2 3]: All the plates are in the dryer: 1, 2, 3, 4, 5, 6. 

In the second example it is possible to wash all the plates in one operation, and then move them all to the dryer.

This is not possible in the third example, because it is not permitted to move more than one plate at the same time. It is possible to wash plates one by one so that they are placed onto the intermediary stack in the reverse order, and then move plates one by one to the dryer. The final order is correct.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
int n, up;
int B[2];
deque<int> v[3];
using P = pair<int, int>;
vector<P> que;
void move(int id, int c) {
  if (c > B[id] || int(v[id].size()) < c) {
    throw 1;
  }
  que.push_back(P(id + 1, c));
  deque<int> buf;
  for (int i = 0; i < c; i++) {
    buf.push_front(v[id].front());
    v[id].pop_front();
  }
  for (int i = 0; i < c; i++) {
    v[id + 1].push_front(buf.front());
    buf.pop_front();
  }
}
void dfs() {
  int sz[3] = {int(v[0].size()), int(v[1].size()), int(v[2].size())};
  if (sz[2] == n) return;
  if (!sz[0] && !sz[1]) throw 1;
  for (int i = 1; i < sz[1]; i++) {
    if (v[1][i - 1] + 1 < v[1][i]) {
      throw 1;
    }
  }
  int m = 0;
  for (int d : v[1]) {
    m = max(m, d);
  }
  if (m == up) {
    int c = 0;
    while (v[1][c] != up) c++;
    move(1, c + 1);
    up -= c + 1;
    dfs();
    return;
  }
  int mi = v[0][0], ma = v[0][0];
  bool di = false;
  int co = 0;
  int r = sz[0];
  int fr = -1;
  for (int i = 1; i < sz[0]; i++) {
    if (v[0][i - 1] + 1 < v[0][i]) {
      r = i;
      break;
    }
    if (v[0][i - 1] > v[0][i]) {
      if (fr == -1) {
        fr = i;
      }
      co++;
    }
    mi = min(mi, v[0][i]);
    ma = max(ma, v[0][i]);
  }
  co++;
  if (co == 1) {
    fr = r;
  }
  if (ma == up) {
    move(0, 1);
    dfs();
    return;
  }
  if (sz[1] && mi < v[1][0]) {
    int c = 0;
    while (c < r && v[0][c] != v[1][0] - 1) {
      c++;
    }
    if (v[0][c] == v[1][0] - 1) c++;
    move(0, c);
    dfs();
    return;
  }
  if (ma - mi + 1 != r) {
    move(0, r);
    dfs();
    return;
  }
  int u = (ma - m);
  if (co >= 3) {
    if (u <= B[1] || r <= min(B[0], B[1])) {
      move(0, fr);
    } else {
      move(0, r);
    }
    dfs();
    return;
  }
  if (fr <= B[0] && r - fr <= B[0] && u <= B[1]) {
    move(0, fr);
    dfs();
    return;
  }
  if (co == 1) {
    if (fr <= min(B[1], B[0])) {
      move(0, fr);
    } else {
      move(0, 1);
    }
    dfs();
    return;
  }
  int bi = m + B[1];
  if (r - fr < B[1]) {
    move(0, min(B[0], min(fr, B[1] - (r - fr))));
    dfs();
    return;
  }
  if (r - fr == B[1] && r <= B[0]) {
    move(0, r);
    dfs();
    return;
  }
  move(0, min(B[0], fr + B[1]));
  dfs();
  return;
}
int main() {
  cin >> n >> B[0] >> B[1];
  up = n;
  for (int i = 0; i < n; i++) {
    int x;
    cin >> x;
    v[0].push_back(x);
  }
  try {
    dfs();
    cout << "YES" << endl;
    cout << que.size() << endl;
    for (auto p : que) {
      cout << p.first << " " << p.second << endl;
    }
  } catch (int a) {
    cout << "NO" << endl;
  }
}
