Problem:


Score : 100 points

Problem Statement

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.

Sample Input 1

3 3
#..
..#
...

Sample Output 1

3
#><
vv#
^^.

The following output is also treated as a correct answer.

3
#><
v.#
^><



Sample input:
3 3
#..
..#
...


Sample output:
3
#><
vv#
^^.

Submission status: Wrong Answer

Solution code:
import sys

def input(): return sys.stdin.readline().strip()
def list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10**9)
INF = 10**19
MOD = 10**9 + 7
EPS = 10**-10

def build_grid(H, W, intv, _type, space=False, padding=True):
    # 入力がスペース区切りかどうか
    if space:
        _input = lambda: input().split()
    else:
        _input = lambda: input()
    _list = lambda: list(map(_type, _input()))
    # 余白の有無
    if padding:
        offset = 1
    else:
        offset = 0
    grid = list2d(H+offset*2, W+offset*2, intv)
    for i in range(offset, H+offset):
        row = _list()
        for j in range(offset, W+offset):
            grid[i][j] = row[j-offset]
    return grid

class Dinic:
    """ 最大流(Dinic)：O(E*V^2) """

    INF = 10**18

    def __init__(self, n):
        self.n = n
        self.links = [[] for _ in range(n)]
        self.depth = None
        self.progress = None
        self.pos = []

    def copy(self):
        res = Dinic(self.n)
        res.links = [[a[:] for a in b] for b in self.links]
        res.pos = [a[:] for a in self.pos]
        return res

    def add_edge(self, _from, to, cap):
        self.pos.append((_from, len(self.links[_from])))
        self.links[_from].append([cap, to, len(self.links[to])])
        self.links[to].append([0, _from, len(self.links[_from]) - 1])

    def bfs(self, s):
        from collections import deque

        depth = [-1] * self.n
        depth[s] = 0
        q = deque([s])
        while q:
            v = q.popleft()
            for cap, to, _ in self.links[v]:
                if cap > 0 and depth[to] < 0:
                    depth[to] = depth[v] + 1
                    q.append(to)
        self.depth = depth

    def dfs(self, v, t, flow):
        if v == t:
            return flow
        links_v = self.links[v]
        for i in range(self.progress[v], len(links_v)):
            self.progress[v] = i
            cap, to, rev = link = links_v[i]
            if cap == 0 or self.depth[v] >= self.depth[to]:
                continue
            d = self.dfs(to, t, min(flow, cap))
            if d == 0:
                continue
            link[0] -= d
            self.links[to][rev][0] += d
            return d
        return 0

    def flow(self, s, t):
        INF = Dinic.INF
        flow = 0
        while True:
            self.bfs(s)
            if self.depth[t] < 0:
                return flow
            self.progress = [0] * self.n
            current_flow = self.dfs(s, t, INF)
            while current_flow > 0:
                flow += current_flow
                current_flow = self.dfs(s, t, INF)

    def get_edge(self, i):
        e = self.links[self.pos[i][0]][self.pos[i][1]]
        re = self.links[e[1]][e[2]]
        # from, to, cap, flow
        return (self.pos[i][0], e[1], e[0]+re[0], re[0])

    def get_edges(self):
        M = len(self.pos)
        res = []
        for i in range(M):
            res.append(self.get_edge(i))
        return res

N, M = MAP()
grid = build_grid(N, M, '#', str)
N += 2; M += 2

dinic = Dinic(N*M+2)
s = N*M
t = N*M + 1

directions = ((1, 0), (-1, 0), (0, 1), (0, -1))
for i in range(1, N-1):
    for j in range(1, M-1):
        if grid[i][j] == '#':
            continue
        u = M*i + j
        if u % 2 == 1:
            dinic.add_edge(s, u, 1)
        else:
            dinic.add_edge(u, t, 1)
        for di, dj in directions:
            ni, nj = i+di, j+dj
            v = M*ni + nj
            if grid[ni][nj] == '.':
                dinic.add_edge(u, v, 1)

res = dinic.flow(s, t)
edges = dinic.get_edges()
for u, v, cap, f in edges:
    if u not in [s, t] and v not in [s, t] and f:
        ci, cj = divmod(u, M)
        ni, nj = divmod(v, M)
        if ci+1 == ni:
            grid[ci][cj] = 'v'
            grid[ni][nj] = '^'
        elif ci == ni+1:
            grid[ci][cj] = '^'
            grid[ni][nj] = 'v'
        elif cj+1 == nj:
            grid[ci][cj] = '>'
            grid[ni][nj] = '<'
        elif cj == nj+1:
            grid[ci][cj] = '<'
            grid[ni][nj] = '>'

print(res)
for i in range(1, N-1):
    print(''.join(grid[i][1:M-1]))

Submission status: Wrong Answer

Solution code:
class Weigthed_Digraph:
    #入力定義
    def __init__(self,vertex=[]):
        self.vertex=set(vertex)

        self.edge_number=0
        self.vertex_number=len(vertex)

        self.adjacent_out={v:{} for v in vertex} #出近傍(vが始点)
        self.adjacent_in={v:{} for v in vertex} #入近傍(vが終点)

    #頂点の追加
    def add_vertex(self,*adder):
        for v in adder:
            if v not in self.vertex:
                self.adjacent_in[v]={}
                self.adjacent_out[v]={}

                self.vertex_number+=1
                self.vertex.add(v)

    #辺の追加(更新)
    def add_edge(self,From,To,weight=1):
        for v in [From,To]:
            if v not in self.vertex:
                self.add_vertex(v)

        if To not in self.adjacent_in[From]:
            self.edge_number+=1

        self.adjacent_out[From][To]=weight
        self.adjacent_in[To][From]=weight

    #辺を除く
    def remove_edge(self,From,To):
        for v in [From,To]:
            if v not in self.vertex:
                self.add_vertex(v)

        if To in self.adjacent_out[From]:
            del self.adjacent_out[From][To]
            del self.adjacent_in[To][From]
            self.edge_number-=1

    #頂点を除く
    def remove_vertex(self,*vertexes):
        for  v in vertexes:
            if v in self.vertex:
                self.vertex_number-=1

                for u in self.adjacent_out[v]:
                    del self.adjacent_in[u][v]
                    self.edge_number-=1
                del self.adjacent_out[v]

                for u in self.adjacent_in[v]:
                    del self.adjacent_out[u][v]
                    self.edge_number-=1
                del self.adjacent_in[v]

    #Walkの追加
    def add_walk(self,*walk):
        pass

    #Cycleの追加
    def add_cycle(self,*cycle):
        pass

    #頂点の交換
    def __vertex_swap(self,p,q):
        self.vertex.sort()

    #グラフに頂点が存在するか否か
    def vertex_exist(self,v):
        return v in self.vertex

    #グラフに辺が存在するか否か
    def edge_exist(self,From,To):
        if not(self.vertex_exist(From) and self.vertex_exist(To)):
            return False
        return To in self.adjacent_out[From]

    #近傍
    def neighbohood(self,v):
        if not self.vertex_exist(v):
            return []
        return list(self.adjacent[v])

    #出次数
    def out_degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return len(self.adjacent_out[v])

    #入次数
    def in_degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return len(self.adjacent_in[v])

    #次数
    def degree(self,v):
        if not self.vertex_exist(v):
            return 0

        return self.out_degree(v)-self.in_degree(v)

    #頂点数
    def vertex_count(self):
        return len(self.vertex)

    #辺数
    def edge_count(self):
        return self.edge_number

    #頂点vを含む連結成分
    def connected_component(self,v):
        pass

def Flow(D,source,sink,Mode=False):
    """Source sからSink tへの最大流問題を解く.
    Mode:
    True---各頂点の流し方も返す
    False---解答のみ
    """
    s,t=source,sink

    H={v:[] for v in D.vertex}

    for u in D.vertex:
        for v in D.adjacent_out[u]:
            F=[v,D.adjacent_out[u][v],None]
            F[2]=B=[u,0,F]
            H[u].append(F)
            H[v].append(B)

    def dfs(v,t,f):
        if v==t:
            return f

        U[v]=True
        for e in H[v]:
            w,cap,inv=e

            if cap and (not U[w]):
                d=dfs(w,t,min(f,cap))
                if d:
                    e[1]-=d
                    inv[1]+=d
                    return d
        return 0

    inf=float("inf")
    f=inf
    flow=0
    while f:
        U={v:False for v in D.vertex}
        f=dfs(s,t,inf)
        flow+=f

    if Mode:
        R={}
        for v in D.vertex:
            R[v]={}
            for S in H[v]:
                w=S[0]
                if w in D.adjacent_out[v]:
                    R[v][w]=S[-1][1]

        return flow,R
    else:
        return flow
#================================================
N,M=map(int,input().split())
D=Weigthed_Digraph([(y,x) for x in range(1,M+1) for y in range(1,N+1)])
D.add_vertex("s","t")

S=["*"*(M+2) for _ in range(N+2)]
for i in range(1,N+1):
    S[i]="*"+input()+"*"

H=[(1,0),(-1,0),(0,1),(0,-1)]
for y in range(1,N+1):
    for x in range(1,M+1):
        if S[y][x]!=".":
            continue

        if (x+y)%2:
            D.add_edge("s",(y,x),1)
            for (a,b) in H:
                if S[y+a][x+b]==".":
                    D.add_edge((y,x),(y+a,x+b),1)
        else:
            D.add_edge((y,x),"t",1)

print(Flow(D,"s","t"))

Submission status: Wrong Answer

Solution code:
import networkx as nx

R, C = [int(x) for x in input().split()]
grid = [list(input()) for r in range(R)]


def pack(r, c):
    return r * C + c


graph = nx.Graph()
top_nodes = []  # top half of the bipartite graph
for r in range(R - 1):
    for c in range(C - 1):
        if grid[r][c] == grid[r + 1][c] == ".":
            u, v = pack(r, c), pack(r + 1, c)
            graph.add_edge(u, v)
            if (r + c) % 2 == 0:
                top_nodes.append(v)
            else:
                top_nodes.append(u)
        if grid[r][c] == grid[r][c + 1] == ".":
            u, v = pack(r, c), pack(r, c + 1)
            graph.add_edge(u, v)
            if (r + c) % 2 == 0:
                top_nodes.append(v)
            else:
                top_nodes.append(u)

matching = nx.bipartite.maximum_matching(graph, top_nodes=top_nodes)

count = 0
for u, v in matching.items():
    if u > v:
        assert matching[v] == u
        r1, c1 = divmod(u, C)
        r2, c2 = divmod(v, C)
        if r1 == r2:
            if c1 > c2:
                c1, c2 = c2, c1
            grid[r1][c1], grid[r2][c2] = ">", "<"
        elif c1 == c2:
            if r1 > r2:
                r1, r2 = r2, r1
            grid[r1][c1] = "v"
            grid[r2][c2] = "^"
        count += 1

print(count)
for row in grid:
    print("".join(row))

Submission status: Wrong Answer

Solution code:

"""
sから奇数へ，奇数から偶数へ，偶数からtへ
"""
def main():
    # Dinic's algorithm
    import collections
    class Dinic:
        def __init__(self, vnum):
            self.edge = [[] for i in range(vnum)]
            self.n = vnum
            self.inf = 10**10
        def add_edge(self, start, end, c):
            self.edge[start].append([end, c, len(self.edge[end])])
            self.edge[end].append([start, 0, len(self.edge[start])-1])
        def bfs(self, vst):
            dist = [-1]*self.n
            dist[vst] = 0
            Q = collections.deque([vst])
            while Q:
                nv = Q.popleft()
                for vt, c, r in self.edge[nv]:
                    if dist[vt] == -1 and c > 0:
                        dist[vt] = dist[nv] + 1
                        Q.append(vt)
            self.dist = dist
        def dfs(self, nv, en, nf):
            nextv = self.nextv
            if nv == en:
                return nf
            dist = self.dist
            ist = nextv[nv]
            for i, (vt, c, r) in enumerate(self.edge[nv][ist:], ist):
                if dist[nv] < dist[vt] and c > 0:
                    df = self.dfs(vt, en, min(nf, c))
                    if df > 0:
                        self.edge[nv][i][1] -= df
                        self.edge[vt][r][1] += df
                        return df
                nextv[nv] += 1
            return 0
        def get_max_flow(self, st, en):
            mf = 0
            while True:
                self.bfs(st)
                if self.dist[en] == -1:
                    break
                self.nextv = [0]*self.n
                while True:
                    fl = self.dfs(st, en, self.inf)
                    if fl > 0:
                        mf += fl
                    else:
                        break
            return mf
        
    mod=10**9+7
    N,M=map(int, input().split())
    S=[]
    for _ in range(N):
        s=list(input())
        S.append(s)
        
    din=Dinic(N*M+2)
    s=N*M
    t=N*M+1
    
    # 場外との流路
    for i in range(N):
        for j in range(M):
            if S[i][j]=="#":
                continue
            v=M*i + j
            if (i+j)%2==1:
                din.add_edge(s,v,1)
            else:
                din.add_edge(v,t,1)
                
    # 場内
    dx=[0,0,1,-1]
    dy=[1,-1,0,0]
    
    for i in range(N):
        for j in range(M):
            if S[i][j]=="#":
                continue
            v=M*i + j
            if (i+j)%2==1:
                for k in range(4):
                    ni=i+dx[k]
                    nj=j+dy[k]
                    
                    if 0<=ni<N and 0<=nj<M:
                        if S[ni][nj]== "#":
                            continue
                        nv=M*ni + nj
                        din.add_edge(v,nv,1)
                        
    
    ans=din.get_max_flow(s,t)
    
    T=[s[:] for s in S]
            
    
    for v in range(N*M):
        if v%2==1:
            i,j = divmod(v,M)
            if S[i][j]==".":
                for nv,cap,_ in din.edge[v]:
                    if cap==0 and nv!=t and nv!=s:#使った辺を見る
                        ni,nj=divmod(nv,M)
                        # print(i,j," ",ni,nj)
                        if i==ni:
                            if j<nj:
                                T[i][j]=">"
                                T[ni][nj]="<"
                            else:
                                T[i][j]="<"
                                T[ni][nj]=">"
                        else:
                            if i<ni:
                                T[i][j]="v"
                                T[ni][nj]="^"
                            else:
                                T[i][j]="^"
                                T[ni][nj]="v"
                                
                                
    print(ans)
    for i in range(N):
        print(''.join(map(str, T[i])))
                                
                                
                                
            
    
                    
        
    
    

main()

Submission status: Wrong Answer

Solution code:
import sys
from collections import deque
sys.setrecursionlimit(100000)
input = sys.stdin.readline


class Dinic:
    def __init__(self, v):
        self.vertice = v
        self.inf = int(1e9)
        self.graph = [[] for i in range(v)]
        self.level = [0]*v
        self.iter = [0]*v
    
    def add_edge(self, fr, to, cap, reverse=True):
        self.graph[fr].append([to, cap, len(self.graph[to])])
        cap2 = cap if reverse else 0
        self.graph[to].append([fr, cap2, len(self.graph[fr])-1])
    
    def bfs(self, s):
        self.level = [-1]*self.vertice
        que = deque([])
        self.level[s] = 0
        que.append(s)

        while que:
            v = que.popleft()
            for i in range(len(self.graph[v])):
                e = self.graph[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.append(e[0])
    
    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.graph[v])):
            self.iter[v] = i
            e = self.graph[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.graph[e[0]][e[2]][1] += d
                    return d
        return 0
    
    def max_flow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0]*self.vertice

            f = self.dfs(s, t, self.inf)
            while f:
                flow += f
                f = self.dfs(s, t, self.inf)

def main():
    n, m = map(int, input().split())
    s = [[1 if x == "#" else 0 for x in input()[:-1]] for i in range(n)]
    
    flow = Dinic(n*m+2)
    start = 0
    end = n*m+1
    direction = [(-1, 0), (1, 0), (0, -1), (0, 1)]
    for i in range(n):
        for j in range(m):
            if s[i][j] == 0:
                if (i+j)%2:
                    flow.add_edge(start, i*m+j+1, 1, reverse=True)
                    for x, y in direction:
                        ni, nj = x + i, y + j
                        if 0 <= ni < n and 0 <= nj < m and s[ni][nj] == 0:
                            flow.add_edge(min(i*m+j+1, ni*m+nj+1), max(i*m+j+1, ni*m+nj+1), 1, reverse=True)
                else:
                    flow.add_edge(i*m+j+1, end, 1, reverse=True)
    
    res = flow.max_flow(start, end)
    print(res)

    ans = [["#" if s[i][j] else "." for j in range(m)] for i in range(n)]

    flow_list = dict()
    for i, g in enumerate(flow.graph):
        for node in g:
            fr, to = i, node[0]
            if fr == start or to == end or to == start or fr == end:
                continue
            cap = node[1]
            if cap != 1:
                if fr > to:
                    fr, to = to, fr
                flow_list[fr-1] = to-1
    
    for k, v in flow_list.items():
        if v-k == m:
            ans[k//m][k%m] = "v"
            ans[v//m][v%m] = "^"
        else:
            ans[k//m][k%m] = ">"
            ans[v//m][v%m] = "<"
    for a in ans:
        print("".join(a))


    
if __name__ == "__main__":
    main()

Submission status: Wrong Answer

Solution code:
import sys
from collections import deque
sys.setrecursionlimit(100000)
input = sys.stdin.readline


class Dinic:
    def __init__(self, v):
        self.vertice = v
        self.inf = int(1e9)
        self.graph = [[] for i in range(v)]
        self.level = [0]*v
        self.iter = [0]*v
    
    def add_edge(self, fr, to, cap, reverse=True):
        self.graph[fr].append([to, cap, len(self.graph[to])])
        cap2 = cap if reverse else 0
        self.graph[to].append([fr, cap2, len(self.graph[fr])-1])
    
    def bfs(self, s):
        self.level = [-1]*self.vertice
        que = deque([])
        self.level[s] = 0
        que.append(s)

        while que:
            v = que.popleft()
            for i in range(len(self.graph[v])):
                e = self.graph[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.append(e[0])
    
    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.graph[v])):
            self.iter[v] = i
            e = self.graph[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.graph[e[0]][e[2]][1] += d
                    return d
        return 0
    
    def max_flow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0]*self.vertice

            f = self.dfs(s, t, self.inf)
            while f:
                flow += f
                f = self.dfs(s, t, self.inf)
def main():
    try:
        n, m = map(int, input().split())
        s = [[1 if x == "#" else 0 for x in input()[:-1]] for i in range(n)]
        
        flow = Dinic(n*m+2)
        start = 0
        end = n*m+1
        direction = [(-1, 0), (1, 0), (0, -1), (0, 1)]
        for i in range(n):
            for j in range(m):
                if s[i][j] == 0:
                    if (i+j)%2:
                        flow.add_edge(start, i*m+j+1, 1, reverse=False)
                        for x, y in direction:
                            ni, nj = x + i, y + j
                            if 0 <= ni < n and 0 <= nj < m and s[ni][nj] == 0:
                                p, q = min(i*m+j+1, ni*m+nj+1), max(i*m+j+1, ni*m+nj+1)
                                flow.add_edge(p, q, 1, reverse=False)
                    else:
                        flow.add_edge(i*m+j+1, end, 1, reverse=False)
    finally:
        return 

    res = flow.max_flow(start, end)
    print(res)

    ans = [["#" if s[i][j] else "." for j in range(n)] for i in range(n)]

    flow_list = []
    for i, g in enumerate(flow.graph):
        for node in g:
            fr, to = i, node[0]
            if fr > to:
                continue
            if fr == start or to == end:
                continue
            cap = node[1]
            if cap == 0:
                flow_list.append((fr-1, to-1))
            
    for k, v in flow_list:
        if v-k == m:
            ans[k//m][k%m] = "v"
            ans[v//m][v%m] = "^"
        else:
            ans[k//m][k%m] = ">"
            ans[v//m][v%m] = "<"

    for a in ans:
        print("".join(a))


    
if __name__ == "__main__":
    main()

Submission status: Wrong Answer

Solution code:
import sys
from collections import deque
sys.setrecursionlimit(100000)
input = sys.stdin.readline


class Dinic:
    def __init__(self, v):
        self.vertice = v
        self.inf = int(1e9)
        self.graph = [[] for i in range(v)]
        self.level = [0]*v
        self.iter = [0]*v
    
    def add_edge(self, fr, to, cap, reverse=True):
        self.graph[fr].append([to, cap, len(self.graph[to])])
        cap2 = cap if reverse else 0
        self.graph[to].append([fr, cap2, len(self.graph[fr])-1])
    
    def bfs(self, s):
        self.level = [-1]*self.vertice
        que = deque([])
        self.level[s] = 0
        que.append(s)

        while que:
            v = que.popleft()
            for i in range(len(self.graph[v])):
                e = self.graph[v][i]
                if e[1] > 0 and self.level[e[0]] < 0:
                    self.level[e[0]] = self.level[v] + 1
                    que.append(e[0])
    
    def dfs(self, v, t, f):
        if v == t:
            return f
        for i in range(self.iter[v], len(self.graph[v])):
            self.iter[v] = i
            e = self.graph[v][i]
            if e[1] > 0 and self.level[v] < self.level[e[0]]:
                d = self.dfs(e[0], t, min(f, e[1]))
                if d > 0:
                    e[1] -= d
                    self.graph[e[0]][e[2]][1] += d
                    return d
        return 0
    
    def max_flow(self, s, t):
        flow = 0
        while True:
            self.bfs(s)
            if self.level[t] < 0:
                return flow
            self.iter = [0]*self.vertice

            f = self.dfs(s, t, self.inf)
            while f:
                flow += f
                f = self.dfs(s, t, self.inf)
def main():
    try:
        n, m = map(int, input().split())
        s = [[1 if x == "#" else 0 for x in input()[:-1]] for i in range(n)]
        
        flow = Dinic(n*m+2)
        start = 0
        end = n*m+1
        direction = [(-1, 0), (1, 0), (0, -1), (0, 1)]
        for i in range(n):
            for j in range(m):
                if s[i][j] == 0:
                    if (i+j)%2:
                        flow.add_edge(start, i*m+j+1, 1, reverse=False)
                        for x, y in direction:
                            ni, nj = x + i, y + j
                            if 0 <= ni < n and 0 <= nj < m and s[ni][nj] == 0:
                                p, q = min(i*m+j+1, ni*m+nj+1), max(i*m+j+1, ni*m+nj+1)
                                flow.add_edge(p, q, 1, reverse=False)
                    else:
                        flow.add_edge(i*m+j+1, end, 1, reverse=False)
        

        res = flow.max_flow(start, end)
        print(res)

        ans = [["#" if s[i][j] else "." for j in range(n)] for i in range(n)]

        flow_list = []
        for i, g in enumerate(flow.graph):
            for node in g:
                fr, to = i, node[0]
                if fr > to:
                    continue
                if fr == start or to == end:
                    continue
                cap = node[1]
                if cap == 0:
                    flow_list.append((fr-1, to-1))
                
        for k, v in flow_list:
            if v-k == m:
                ans[k//m][k%m] = "v"
                ans[v//m][v%m] = "^"
            else:
                ans[k//m][k%m] = ">"
                ans[v//m][v%m] = "<"

        for a in ans:
            print("".join(a))
    finally:
        return

    
if __name__ == "__main__":
    main()