fn getline() -> String {
    let mut res = String::new();
    std::io::stdin().read_line(&mut res).ok();
    res
}

#[allow(unused_macros)]
macro_rules! readl {
    ($t: ty) => {
        {
            let s = getline();
            s.trim().parse::<$t>().unwrap()
        }
    };
    ($( $t: ty),+ ) => {
        {
            let s = getline();
            let mut iter = s.trim().split(' ');
            ($(iter.next().unwrap().parse::<$t>().unwrap(),)*)
        }
    };
}

#[allow(unused_macros)]
macro_rules! readlvec {
    ($t: ty) => {
        {
            let s = getline();
            let iter = s.trim().split(' ');
            iter.map(|x| x.parse().unwrap()).collect::<Vec<$t>>()
        }
    }
}

#[allow(unused_macros)]
macro_rules! debug {
    ($x: expr) => {
        println!("{}: {:?}", stringify!($x), $x)
    }
}

fn printiter<'a, T>(v: &'a T)
where
    &'a T: std::iter::IntoIterator,
    <&'a T as std::iter::IntoIterator>::Item: std::fmt::Display,
{
    for (i, e) in v.into_iter().enumerate() {
        if i != 0 {
            print!(" ");
        }
        print!("{}", e);
    }
    println!("");
}

#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::{BTreeMap, BinaryHeap, HashMap, HashSet};
#[allow(unused_imports)]
use std::collections::btree_map::Entry::{Occupied, Vacant};

fn puta(v: &mut Vec<Vec<char>>, x: usize, y: usize) -> bool {
    if v[x][y] != '.' || v[x][y + 1] != '.' {
        false
    } else {
        v[x][y] = '<';
        v[x][y + 1] = '>';
        true
    }
}

fn putb(v: &mut Vec<Vec<char>>, x: usize, y: usize) -> bool {
    if v[x][y] != '.' || v[x + 1][y] != '.' {
        false
    } else {
        v[x][y] = '^';
        v[x + 1][y] = 'v';
        true
    }
}

fn put(v: &mut Vec<Vec<char>>, mut a: usize, mut b: usize) -> bool {
    let n = v.len();
    let m = v[0].len();
    for i in 0..n / 2 {
        for j in 0..m / 2 {
            let si = i * 2;
            let sj = j * 2;
            if v[si][sj] != '.' || v[si + 1][sj] != '.' || v[si][sj + 1] != '.'
                || v[si + 1][sj + 1] != '.'
            {
                continue;
            }
            if a > 0 {
                puta(v, si, sj);
                a -= 1;
                if a > 0 {
                    puta(v, si+1, sj);
                    a -= 1;
                }
            } else if b > 0 {
                let t = putb(v, si, sj);
                b -= 1;
                if b > 0 {
                    putb(v, si, sj+1);
                    b -= 1;
                }
            }
        }
    }
    if a == 0 && b == 0 {
        true
    } else {
        false
    }
}

fn main() {
    use std::io::Write;
    let out = std::io::stdout();
    let mut out = std::io::BufWriter::new(out.lock());
    macro_rules! print { ($($arg:tt)*) => (write!(out, $($arg)*).unwrap()); }
    macro_rules! println { () => (writeln!(out).unwrap()); ($($arg:tt)*) => (writeln!(out, $($arg)*).unwrap()); }

    let (n, m, a, b) = readl!(usize, usize, usize, usize);
    if n % 2 == 1 && m % 2 == 1 && a >= 2 && b >= 2 && n >= 3 && m >= 3 {
        let mut at = a;
        let mut bt = b;
        at = max(0, at - (2 + (m - 3) / 2));
        bt = max(0, bt - (2 + (n - 3) / 2));
        let n22 = (at + 1) / 2 + (bt + 1) / 2;
        let r22 = (n - 1) * (m - 1) / 4 - 1;

        if n22 <= r22 {
            let mut a = a;
            let mut b = b;
            let mut ans = vec![vec!['.'; m]; n];
            puta(&mut ans, n - 3, m - 3);
            puta(&mut ans, n - 1, m - 2);
            putb(&mut ans, n - 2, m - 3);
            putb(&mut ans, n - 3, m - 1);
            a -= 2;
            b -= 2;
            for i in 0..(n - 3) / 2 {
                if b == 0 {
                    break;
                }
                putb(&mut ans, i * 2, m - 1);
                b -= 1;
            }
            for j in 0..(m - 3) / 2 {
                if a == 0 {
                    break;
                }
                puta(&mut ans, n - 1, j * 2);
                a -= 1;
            }
            put(&mut ans, a, b);
            println!("YES");
            for row in ans {
                for e in row {
                    print!("{}", e);
                }
                println!("");
            }
            return;
        }
    }

    {
        let mut ans = vec![vec!['.'; m]; n];
        let mut a = a;
        let mut b = b;
        if n % 2 == 1 {
            for j in 0..m/2 {
                if a > 0 {
                    puta(&mut ans, n-1, j*2);
                    a -= 1;
                }
            }
        }
        if m % 2 == 1 {
            for i in 0..n/2 {
                if b > 0 {
                    putb(&mut ans, i*2, m-1);
                    b -= 1;
                }
            }
        }
        // debug!(ans);
        if !put(&mut ans, a, b) {
            println!("NO")
        } else {
            println!("YES");
            for row in ans {
                for e in row {
                    print!("{}", e);
                }
                println!("");
            }
        }
    }
}


Measured memory_bytes: 8956