Problem: You are given a grid of N rows and M columns. The square at the i-th row and j-th column will be denoted as (i,j). Some of the squares contain an object. All the remaining squares are empty. The state of the grid is represented by strings S_1,S_2,\cdots,S_N. The square (i,j) contains an object if S_{i,j}= `#` and is empty if S_{i,j}= `.`.

Consider placing 1 \times 2 tiles on the grid. Tiles can be placed vertically or horizontally to cover two adjacent empty squares. Tiles must not stick out of the grid, and no two different tiles may intersect. Tiles cannot occupy the square with an object.

Calculate the maximum number of tiles that can be placed and any configulation that acheives the maximum.

Constraints

* 1 \leq N \leq 100
* 1 \leq M \leq 100
* S_i is a string with length M consists of `#` and `.`.

Input

Input is given from Standard Input in the following format:


N M
S_1
S_2
\vdots
S_N


Output

On the first line, print the maximum number of tiles that can be placed.

On the next N lines, print a configulation that achieves the maximum. Precisely, output the strings t_1,t_2,\cdots,t_N constructed by the following way.

* t_i is initialized to S_i.
* For each (i,j), if there is a tile that occupies (i,j) and (i+1,j), change t_{i,j}:=`v`, t_{i+1,j}:=`^`.
* For each (i,j), if there is a tile that occupies (i,j) and (i,j+1), change t_{i,j}:=`>`, t_{i,j+1}:=`<`.



See samples for further information.

You may print any configulation that maximizes the number of tiles.

Examples

Input

3 3
#..
..#
...


Output

3
#><
vv#
^^.


Input

3 3
..
..#
...


Output

3
><
vv#
^^.

Solution (in PYTHON3):

Solution:
# D - 浮気予防
from collections import deque
from typing import List

Edge = List[int]  # type alias of Edge


class Dinic:
    """Dinic class to solve max-find_max_flow / min-cut problems.
    References:
        https://ikatakos.com/pot/programming_algorithm/graph_theory/maximum_flow
        http://vartkw.hatenablog.com/entry/2016/12/02/002703
    """

    __slots__ = ["_size", "graph", "_depth", "_progress"]

    def __init__(self, size: int) -> None:
        self._size = size
        self.graph: List[List[Edge]] = [[] for _ in range(size)]
        self._depth = [-1] * size
        self._progress = [0] * size

    def add(self, from_: int, to: int, cap: int = 1, is_directed: bool = True) -> None:
        """Add an edge."""
        self.graph[from_].append([to, cap, len(self.graph[to])])
        self.graph[to].append([from_, 0, len(self.graph[from_]) - 1])
        if not is_directed:
            self.add(to, from_, cap)

    def find_max_flow(self, source: int, target: int, inf: int = 1 << 30) -> int:
        """Find the max-find_max_flow from source to target in O(N^{2}M)."""
        flow = 0
        while True:
            self._bfs(source)
            if self._depth[target] < 0:
                break
            self._progress = [0] * self._size
            cur_flow = self._dfs(source, target, inf)
            while cur_flow:
                flow += cur_flow
                cur_flow = self._dfs(source, target, inf)
        return flow

    def _bfs(self, source: int) -> None:
        depth = [-1] * self._size
        depth[source] = 0
        queue = deque([source])
        while queue:
            v = queue.popleft()
            for to, cap, _ in self.graph[v]:
                if cap > 0 > depth[to]:
                    depth[to] = depth[v] + 1
                    queue.append(to)
        self._depth = depth

    def _dfs(self, v: int, target: int, flow: int) -> int:
        if v == target:
            return flow
        v_edges = self.graph[v]
        for i in range(self._progress[v], len(v_edges)):
            self._progress[v] = i
            to, cap, rev = v_edges[i]
            if not cap or self._depth[v] >= self._depth[to]:
                continue
            d = self._dfs(to, target, min(flow, cap))
            if not d:
                continue
            v_edges[i][1] -= d
            self.graph[to][rev][1] += d
            return d
        return 0


def practice2_d():
    # https://atcoder.jp/contests/practice2/tasks/practice2_d
    N, M = map(int, input().split())
    S = [list(input()) for _ in range(N)]
    dc = Dinic(N * M + 2)

    s = N * M
    t = N * M + 1
    for i in range(N):
        for j in range(M):
            if (i + j) % 2 == 0:
                dc.add(s, M * i + j)
            else:
                dc.add(M * i + j, t)

    for i in range(N):
        for j in range(M):
            if j + 1 < M and S[i][j] == "." and S[i][j + 1] == ".":
                u, v = M * i + j, M * i + j + 1
                if (i + j) % 2:
                    u, v = v, u
                dc.add(u, v)
            if i + 1 < N and S[i][j] == "." and S[i + 1][j] == ".":
                u, v = M * i + j, M * (i + 1) + j
                if (i + j) % 2:
                    u, v = v, u
                dc.add(u, v)

    print(dc.find_max_flow(s, t))
    for u in range(N * M + 2):
        for v, cap, _ in dc.graph[u]:
            ui, uj = divmod(u, M)
            vi, vj = divmod(v, M)
            if (
                not (ui + uj) % 2
                and not cap
                and u != s
                and u != t
                and v != s
                and v != t
            ):
                if ui + 1 == vi:
                    S[ui][uj] = "v"
                    S[vi][vj] = "^"
                elif ui == vi + 1:
                    S[ui][uj] = "^"
                    S[vi][vj] = "v"
                elif uj + 1 == vj:
                    S[ui][uj] = ">"
                    S[vi][vj] = "<"
                elif uj == vj + 1:
                    S[ui][uj] = "<"
                    S[vi][vj] = ">"

    for res in S:
        print("".join(res))


if __name__ == "__main__":
    practice2_d()