# Date [ 2020-09-08 14:10:26 ]
# Problem [ d.py ]
# Author Koki_tkg

import sys
# import math
# import bisect
# import numpy as np
# from decimal import Decimal
# from numba import njit, i8, u1, b1 #JIT compiler
# from itertools import combinations, product
from collections import Counter, deque, defaultdict

# sys.setrecursionlimit(10 ** 6)
MOD = 10 ** 9 + 7
INF = 10 ** 9
PI = 3.14159265358979323846

def read_str():      return sys.stdin.readline().strip()
def read_int():      return int(sys.stdin.readline().strip())
def read_ints():     return map(int, sys.stdin.readline().strip().split())
def read_ints2(x):   return map(lambda num: int(num) - x, sys.stdin.readline().strip().split())
def read_str_list(): return list(sys.stdin.readline().strip().split())
def read_int_list(): return list(map(int, sys.stdin.readline().strip().split()))
def GCD(a: int, b: int) -> int: return b if a%b==0 else GCD(b, a%b)
def LCM(a: int, b: int) -> int: return (a * b) // GCD(a, b)

# Dinic's algorithm
class Dinic:
    def __init__(self, n):
        self.N = n
        self.level = None
        self.it = None
        self.G = [[] for i in range(self.N)]

    def add_edge(self, _from, _to, cap):
        self.G[_from].append([_to, cap, len(self.G[_to])])
        self.G[_to].append([_from, 0, len(self.G[_from]) - 1])

    def add_multi_edge(self, v1, v2, cap1, cap2):
        edge1 = [v2, cap1, None]
        edge1[2] = edge2 = [v1, cap2, edge1]
        self.G[v1].append(edge1)
        self.G[v2].append(edge2)

    def bfs(self, s):
        level = [-1] * self.N
        level[s] = 0
        que = deque([s])
        while que:
            v = que.popleft()
            for to, cap, rev in self.G[v]:
                if cap > 0 and level[to] < 0:
                    level[to] = level[v] + 1
                    que.append(to)
        self.level = level

    def dfs(self, v, t, flow):
        if v == t: return flow
        for i in range(self.it[v], len(self.G[v])):
            self.it[v] = i
            to, cap, rev = e =self.G[v][i]
            if cap > 0 and self.level[v] < self.level[to]:
                d = self.dfs(to, t, min(flow, cap))
                if d > 0:
                    e[1] -= d
                    self.G[to][rev][1] += d
                    return d
        return 0

    def max_flow(self, s, t):
        flow = 0
        INF = 10**18
        while True:
            self.bfs(s)
            if self.level[t] < 0: return flow
            self.it = [0] * self.N
            f = self.dfs(s, t, INF)
            while f > 0:
                flow += f
                f = self.dfs(s, t, INF)

def Main():
    n, m = read_ints()
    grid = [list(read_str()) for _ in range(n)]
    mf = Dinic(n*m + 2)
    start = n * m
    end = start + 1
    dir = [(1, 0), (0, 1)]
    
    for y in range(n):
        for x in range(m):
            if (y + x) % 2 == 0:
                mf.add_edge(start, m*y + x, 1)
            else:
                mf.add_edge(m*y + x, end, 1)
            
            if grid[y][x] == '.':
                for dy, dx in dir:
                    ny = y + dy; nx = x + dx
                    if ny < n and nx < m and grid[ny][nx] == '.':
                        f, t = y*m + x, ny*m + nx
                        if (y + x) % 2: f, t = t, f
                        mf.add_edge(f, t, 1)

    ans = mf.max_flow(start, end)    

    for y in range(n):
        for x in range(m):
            for to, cap, rev in mf.G[y*m+x]:
                ny, nx = divmod(to, m)
                if (y + x) % 2 == 0 and cap == 0 and to != start and to != end and (y*m+x) != start and (y*m+x) != end:
                    if y + 1 == ny: grid[y][x] = 'v'; grid[ny][nx] = '^'
                    elif y == ny + 1: grid[y][x] = '^'; grid[ny][nx] = 'v'
                    elif x + 1 == nx: grid[y][x] = '>'; grid[ny][nx] = '<'
                    elif x == nx + 1: grid[y][x] = '<'; grid[ny][nx] = '>'
                        
    print(ans)
    print(*[''.join(ret) for ret in grid], sep='\n')

if __name__ == '__main__':
    Main()

Measured memory_bytes: 18536