import sys

import itertools

import numpy as np

import networkx as nx



read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



N, M = list(map(int, readline().split()))

S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')



A = []

B = []

E = []



for i, j in itertools.product(list(range(N)), list(range(M))):

    if S[i, j] == '#':

        continue

    elif (i + j) & 1:

        A.append((i, j))

    else:

        B.append((i, j))



for i, j in A:

    for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):

        i1, j1 = i + dx, j + dy

        if 0 <= i1 < N and 0 <= j1 < M and S[i1, j1] != '#':

            E.append(((i, j), (i1, j1)))



G = nx.Graph()

G.add_nodes_from(A, bipartite=0)

G.add_nodes_from(B, bipartite=1)

G.add_edges_from(E)



M = nx.bipartite.eppstein_matching(G, A)

for key, item in list(M.items()):

    i, j = key

    i1, j1 = item

    if i1 == i + 1:

        a, b = 'v', '^'

    elif i1 == i - 1:

        a, b = '^', 'v'

    elif j1 == j + 1:

        a, b = '>', '<'

    else:

        a, b = '<', '>'

    S[i, j], S[i1, j1] = a, b



print((len(M) // 2))

for row in S:

    print((''.join(row)))

import sys

import itertools

import numpy as np

import networkx as nx



read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



N, M = list(map(int, readline().split()))

S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')



A = []

B = []

E = []



for i, j in itertools.product(list(range(N)), list(range(M))):

    if S[i, j] == '#':

        continue

    elif (i + j) & 1:

        A.append((i, j))

    else:

        B.append((i, j))



for i, j in A:

    for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):

        i1, j1 = i + dx, j + dy

        if 0 <= i1 < N and 0 <= j1 < M and S[i1, j1] != '#':

            E.append(((i, j), (i1, j1)))



G = nx.Graph()

G.add_nodes_from(A, bipartite=0)

G.add_nodes_from(B, bipartite=1)

G.add_edges_from(E)



M = nx.bipartite.maximum_matching(G, A)

for key, item in list(M.items()):

    i, j = key

    i1, j1 = item

    if i1 == i + 1:

        a, b = 'v', '^'

    elif i1 == i - 1:

        a, b = '^', 'v'

    elif j1 == j + 1:

        a, b = '>', '<'

    else:

        a, b = '<', '>'

    S[i, j], S[i1, j1] = a, b



print((len(M) // 2))

for row in S:

    print((''.join(row)))

import sys
import itertools
import numpy as np
import networkx as nx

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
N, M = list(map(int, readline().split()))
S = np.frombuffer(read(), "S1").reshape(N, -1)[:, :M].astype("U1")
A = []
B = []
E = []
for i, j in itertools.product(list(range(N)), list(range(M))):
    if S[i, j] == "#":
        continue
    elif (i + j) & 1:
        A.append((i, j))
    else:
        B.append((i, j))
for i, j in A:
    for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):
        i1, j1 = i + dx, j + dy
        if 0 <= i1 < N and 0 <= j1 < M and S[i1, j1] != "#":
            E.append(((i, j), (i1, j1)))
G = nx.Graph()
G.add_nodes_from(A, bipartite=0)
G.add_nodes_from(B, bipartite=1)
G.add_edges_from(E)
M = nx.bipartite.eppstein_matching(G, A)
for key, item in list(M.items()):
    i, j = key
    i1, j1 = item
    if i1 == i + 1:
        a, b = "v", "^"
    elif i1 == i - 1:
        a, b = "^", "v"
    elif j1 == j + 1:
        a, b = ">", "<"
    else:
        a, b = "<", ">"
    S[i, j], S[i1, j1] = a, b
print((len(M) // 2))
for row in S:
    print(("".join(row)))

import sys
import itertools
import numpy as np
import networkx as nx

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
N, M = list(map(int, readline().split()))
S = np.frombuffer(read(), "S1").reshape(N, -1)[:, :M].astype("U1")
A = []
B = []
E = []
for i, j in itertools.product(list(range(N)), list(range(M))):
    if S[i, j] == "#":
        continue
    elif (i + j) & 1:
        A.append((i, j))
    else:
        B.append((i, j))
for i, j in A:
    for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)):
        i1, j1 = i + dx, j + dy
        if 0 <= i1 < N and 0 <= j1 < M and S[i1, j1] != "#":
            E.append(((i, j), (i1, j1)))
G = nx.Graph()
G.add_nodes_from(A, bipartite=0)
G.add_nodes_from(B, bipartite=1)
G.add_edges_from(E)
M = nx.bipartite.maximum_matching(G, A)
for key, item in list(M.items()):
    i, j = key
    i1, j1 = item
    if i1 == i + 1:
        a, b = "v", "^"
    elif i1 == i - 1:
        a, b = "^", "v"
    elif j1 == j + 1:
        a, b = ">", "<"
    else:
        a, b = "<", ">"
    S[i, j], S[i1, j1] = a, b
print((len(M) // 2))
for row in S:
    print(("".join(row)))

-M = nx.bipartite.eppstein_matching(G, A) +M = nx.bipartite.maximum_matching(G, A)