#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define TRACE(x) cout << #x << " = " << x << endl
#define _ << " _ " <<

typedef long long llint;

void no() {
  puts("NO");
  exit(0);
}

void putVer(int i, int j, vector<string>& ret) {
  ret[i][j] = '^';
  ret[i+1][j] = 'v';
}

void putHor(int i, int j, vector<string>& ret) {
  ret[i][j] = '<';
  ret[i][j+1] = '>';
}

void solve(int N, int M, int A, int B, vector<string>& ret) {
  bool odd = N%2 && M%2 && N >= 3 && M >= 3;

  if (N % 2 == 1) {
    for (int i = 0; i + 1 < M; i += 2) {
      if (odd && i >= M-3) continue;
      if (A > 0) putHor(N-1, i, ret), A--;
    }
  }
  if (M % 2 == 1) {
    for (int i = 0; i + 1 < N; i += 2) {
      if (odd && i >= N-3) continue;
      if (B > 0) putVer(i, M-1, ret), B--;
    }
  }

  for (int i = 0; i + 1 < N; i += 2) {
    for (int j = 0; j + 1 < M; j += 2) {
      if (odd && i+1 >= N-3 && j+1 >= M-3) continue;
      if (A >= 2 && A >= B) {
        putHor(i, j, ret);
        putHor(i+1, j, ret);
        A -= 2;
      } else if (B >= 2) {
        putVer(i, j, ret);
        putVer(i, j+1, ret);
        B -= 2;
      } else if (A >= 1) {
        putHor(i, j, ret);
        A--;
      } else if (B >= 1) {
        putVer(i, j, ret);
        B--;
      }
    }
  }

  if (odd) {
    if (A <= 1) {
      if (B > 3) no();
      REP(i, B) putVer(N-3, M-3+i, ret);
      if (A == 1) putHor(N-1, M-3, ret);
    } else if (B <= 1) {
      if (A > 3) no();
      REP(i, A) putHor(N-3+i, M-3, ret);
      if (B == 1) putVer(N-3, M-1, ret);
    } else if (A == 2 && B == 2) {
      putHor(N-3, M-3, ret);
      putVer(N-3, M-1, ret);
      putVer(N-2, M-3, ret);
      putHor(N-1, M-2, ret);
    } else {
      no();
    }
  } else {
    if (A > 0 || B > 0) no();
  }
}

int main(void) {
  int N, M, A, B;
  scanf("%d %d %d %d", &N, &M, &A, &B);
  vector<string> ret(N, string(M, '.'));

  solve(N, M, A, B, ret);

  puts("YES");
  REP(i, N) puts(ret[i].c_str());
  return 0;
}

### Prompt

Please provide a cpp coded solution to the problem described below:

Takahashi has an N \times M grid, with N horizontal rows and M vertical columns. Determine if we can place A 1 \times 2 tiles (1 vertical, 2 horizontal) and B 2 \times 1 tiles (2 vertical, 1 horizontal) satisfying the following conditions, and construct one arrangement of the tiles if it is possible:

* All the tiles must be placed on the grid.
* Tiles must not stick out of the grid, and no two different tiles may intersect.
* Neither the grid nor the tiles may be rotated.
* Every tile completely covers exactly two squares.

Constraints

* 1 \leq N,M \leq 1000
* 0 \leq A,B \leq 500000
* N, M, A and B are integers.

Input

Input is given from Standard Input in the following format:


N M A B


Output

If it is impossible to place all the tiles, print `NO`. Otherwise, print the following:


YES
c_{11}...c_{1M}
:
c_{N1}...c_{NM}


Here, c_{ij} must be one of the following characters: `.`, `<`, `>`, `^` and `v`. Represent an arrangement by using each of these characters as follows:

* When c_{ij} is `.`, it indicates that the square at the i-th row and j-th column is empty;
* When c_{ij} is `<`, it indicates that the square at the i-th row and j-th column is covered by the left half of a 1 \times 2 tile;
* When c_{ij} is `>`, it indicates that the square at the i-th row and j-th column is covered by the right half of a 1 \times 2 tile;
* When c_{ij} is `^`, it indicates that the square at the i-th row and j-th column is covered by the top half of a 2 \times 1 tile;
* When c_{ij} is `v`, it indicates that the square at the i-th row and j-th column is covered by the bottom half of a 2 \times 1 tile.

Examples

Input

3 4 4 2


Output

YES
<><>
^<>^
v<>v


Input

4 5 5 3


Output

YES
<>..^
^.<>v
v<>.^
<><>v


Input

7 9 20 20


Output

NO

### Response

```cpp
#include <algorithm>
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define TRACE(x) cout << #x << " = " << x << endl
#define _ << " _ " <<

typedef long long llint;

void no() {
  puts("NO");
  exit(0);
}

void putVer(int i, int j, vector<string>& ret) {
  ret[i][j] = '^';
  ret[i+1][j] = 'v';
}

void putHor(int i, int j, vector<string>& ret) {
  ret[i][j] = '<';
  ret[i][j+1] = '>';
}

void solve(int N, int M, int A, int B, vector<string>& ret) {
  bool odd = N%2 && M%2 && N >= 3 && M >= 3;

  if (N % 2 == 1) {
    for (int i = 0; i + 1 < M; i += 2) {
      if (odd && i >= M-3) continue;
      if (A > 0) putHor(N-1, i, ret), A--;
    }
  }
  if (M % 2 == 1) {
    for (int i = 0; i + 1 < N; i += 2) {
      if (odd && i >= N-3) continue;
      if (B > 0) putVer(i, M-1, ret), B--;
    }
  }

  for (int i = 0; i + 1 < N; i += 2) {
    for (int j = 0; j + 1 < M; j += 2) {
      if (odd && i+1 >= N-3 && j+1 >= M-3) continue;
      if (A >= 2 && A >= B) {
        putHor(i, j, ret);
        putHor(i+1, j, ret);
        A -= 2;
      } else if (B >= 2) {
        putVer(i, j, ret);
        putVer(i, j+1, ret);
        B -= 2;
      } else if (A >= 1) {
        putHor(i, j, ret);
        A--;
      } else if (B >= 1) {
        putVer(i, j, ret);
        B--;
      }
    }
  }

  if (odd) {
    if (A <= 1) {
      if (B > 3) no();
      REP(i, B) putVer(N-3, M-3+i, ret);
      if (A == 1) putHor(N-1, M-3, ret);
    } else if (B <= 1) {
      if (A > 3) no();
      REP(i, A) putHor(N-3+i, M-3, ret);
      if (B == 1) putVer(N-3, M-1, ret);
    } else if (A == 2 && B == 2) {
      putHor(N-3, M-3, ret);
      putVer(N-3, M-1, ret);
      putVer(N-2, M-3, ret);
      putHor(N-1, M-2, ret);
    } else {
      no();
    }
  } else {
    if (A > 0 || B > 0) no();
  }
}

int main(void) {
  int N, M, A, B;
  scanf("%d %d %d %d", &N, &M, &A, &B);
  vector<string> ret(N, string(M, '.'));

  solve(N, M, A, B, ret);

  puts("YES");
  REP(i, N) puts(ret[i].c_str());
  return 0;
}

```