//MIPT Cryptozoology 17.2
#pragma comment(linker, "/STACK:512000000")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
using namespace std;

#define all(a) a.begin(), a.end()
typedef long long li;
typedef long double ld;
void solve(__attribute__((unused)) bool);
void precalc();
clock_t start;
#define FILENAME ""

int main() {
#ifdef AIM
    string s = FILENAME;
    //assert(!s.empty());
    freopen("/home/alexandero/ClionProjects/cryptozoology/input.txt", "r", stdin);
#else
    //freopen(FILENAME ".in", "r", stdin);
    //freopen(FILENAME ".out", "w", stdout);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
#endif
    start = clock();
    int t = 1;
#ifndef AIM
    cout.sync_with_stdio(0);
    cin.tie(0);
#endif
    precalc();
    cout.precision(10);
    cout << fixed;
    //cin >> t;
    int testNum = 1;
    while (t--) {
        //cout << "Case #" << testNum++ << ": ";
        //cerr << testNum << endl;
        solve(true);
        //cerr << testNum - 1 << endl;
    }
    cout.flush();
#ifdef AIM1
    while (true) {
      solve(false);
  }
#endif

#ifdef AIM
    cout.flush();
    auto end = clock();

    usleep(10000);
    print_stats(end - start);
    usleep(10000);
#endif

    return 0;
}

void precalc() {
}

template<typename T>
inline T nxt() {
    T cur;
    cin >> cur;
    return cur;
}

//#define int li
//const int mod = 1000000007;

void fail() {
    cout << "NO\n";
}

void solve(__attribute__((unused)) bool read) {
    int n, m, a, b;
    cin >> n >> m >> a >> b;
    bool need_swap = false;
    if (m % 2) {
        swap(n, m);
        need_swap = true;
        swap(a, b);
    }

    vector<string> res(n, string(m, '.'));

    int start_row = 0;
    if (n % 2) {
        ++start_row;
        for (int i = 0; a > 0 && i + 1 < m; i += 2) {
            if (a > 0) {
                res[0][i] = '<';
                res[0][i + 1] = '>';
                --a;
            }
        }
    }
    for (int j = 0; j + 1 < m && a > 0; j += 2) {
        for (int i = start_row; a > 0 && i < n; i += 2) {
            if (a == 1 && m % 2 == 1) {
                res[n - 1][m - 2] = '<';
                res[n - 1][m - 1] = '>';
                --a;
                continue;
            }
            res[i][j] = '<';
            res[i][j + 1] = '>';
            --a;
            if (a > 0 && i + 1 < n) {
                res[i + 1][j] = '<';
                res[i + 1][j + 1] = '>';
                --a;
            }
        }
    }

    if (a > 0) {
        fail();
        return;
    }

    /*for (auto vec : res) {
        cout << vec << endl;
    }*/

    for (int i = 0; i < n && b > 0; ++i) {
        for (int j = 0; b > 0 && j < m; ++j) {
            if (res[i][j] == '.' && i + 1 < n && res[i + 1][j] == '.') {
                res[i][j] = '^';
                res[i + 1][j] = 'v';
                --b;
            }
        }
    }

    if (b > 0) {
        fail();
        return;
    }

    if (need_swap) {
        vector<string> ans(m, string(n, '.'));
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < m; ++j) {
                char c = res[i][j];
                char res = 0;
                switch(c) {
                    case '<':
                        res = '^';
                        break;
                    case '>':
                        res = 'v';
                        break;
                    case '^':
                        res = '<';
                        break;
                    case 'v':
                        res = '>';
                        break;
                    case '.':
                        res = '.';
                        break;
                    default:
                        assert(false);
                }
                ans[j][i] = res;
            }
        }
        ans.swap(res);
    }

    cout << "YES\n";
    for (auto vec : res) {
        cout << vec << "\n";
    }

}

Measured memory_bytes: 2944