output_description: 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.
  
  * * *
input_description: Input is given from Standard Input in the following format:
  
      
      
      N M A B
attempt: import sys
  
  input = sys.stdin.readline
  
  import numpy as np
  
  N, M, A, B = map(int, input().split())
  
  
  def solve(N, M, A, B):
      grid = np.full((N, M), ".", dtype="U1")
      put_row = np.full((N, M - 1), 10**9, dtype=np.int32)
      if N % 2 == 0:
          for n in range(0, M // 2):
              put_row[:, n + n] = np.arange(N * n, N * (n + 1))
      elif M % 2 == 0:
          # N-1行目を埋めたあと、2個ずつ
          put_row[-1, ::2] = np.arange(M // 2)
          x = M // 2
          for n in range(M // 2):
              put_row[:-1, n + n] = np.arange(x, x + N - 1)
              x += N - 1
      else:
          # N-1行目を右優先で埋めたあと、左上から
          put_row[-1, 1::2] = np.arange(M // 2)
          x = M // 2
          for n in range(M // 2):
              put_row[:-1, n + n] = np.arange(x, x + N - 1)
              x += N - 1
      # 置くべき優先度を定義し終わった
      x, y = np.where(put_row < A)
      if len(x) != A:
          print("NO")
          return
      grid[x, y] = "<"
      grid[x, y + 1] = ">"
      # 空きます
      put_col = grid == "."
      # 下も空いている（上側としておける）
      put_col[:-1] &= put_col[1:]
      put_col[-1] = 0
      for n in range(1, N):
          # ひとつ上から置けるならやめる
          put_col[n] &= ~put_col[n - 1]
      x, y = np.where(put_col)
      x = x[:B]
      y = y[:B]
      if len(x) != B:
          print("NO")
          return
      grid[x, y] = "^"
      grid[x + 1, y] = "v"
      print("YES")
      print("\n".join("".join(row) for row in grid))
      return
  
  
  solve(N, M, A, B)
  
problem_description: Statement
  
  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.
samples: [{"input": "3 4 4 2", "output": "YES\n    <><>\n    ^<>^\n    v<>v\n    \n\nThis is one example of a way to place four 1 \\times 2 tiles and three 2 \\times\n1 tiles on a 3 \\times 4 grid.\n\n* * *"}, {"input": "4 5 5 3", "output": "YES\n    <>..^\n    ^.<>v\n    v<>.^\n    <><>v\n    \n\n* * *"}, {"input": "7 9 20 20", "output": "NO"}]