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.#
^><

Solution in Lua (LuaJIT 2.1.0) (judge verdict: Accepted)

-- Hopcroft-Karp
HKmatch = {}

HKmatch.create = function(self, an, bn)
  self.dst = {}
  self.edge = {}
  for i = 1, an do
    self.dst[i] = false
    self.edge[i] = {}
  end
  self.src = {}
  self.invcnt = {}
  self.invs = {}
  self.invpos = {}
  self.padded = {}
  for i = 1, bn do
    self.src[i] = false
    self.invs[i] = {}
  end
  self.p = {}
  self.tasks = {}
  self.level = {}
end

HKmatch.addEdge = function(self, a, b)
  table.insert(self.edge[a], b)
  if not self.dst[a] and not self.src[b] then
    self.dst[a] = b
    self.src[b] = a
  end
end

HKmatch.makeAugPath = function(self)
  local tasknum = 0
  local tasks = self.tasks
  local level = self.level
  local edge = self.edge
  local src = self.src
  local an = #self.dst
  local bn = #src
  local invcnt, invs = self.invcnt, self.invs
  local p, psize = self.p, 0
  local padded = self.padded
  local lvinf = an + 1
  for i = 1, an do
    if self.dst[i] then
      level[i] = lvinf
    else
      tasknum = tasknum + 1
      tasks[tasknum] = i
      level[i] = 1
    end
  end
  for i = 1, bn do
    invcnt[i] = 0
    padded[i] = false
  end
  local done = 0
  local lvmax = lvinf
  while done < tasknum do
    done = done + 1
    local a = tasks[done]
    if lvmax < level[a] then break end
    for i = 1, #edge[a] do
      local b = edge[a][i]
      local sb = src[b]
      if sb then
        if level[sb] == lvinf then
          tasknum = tasknum + 1
          tasks[tasknum] = sb
          level[sb] = level[a] + 1
          invcnt[b] = invcnt[b] + 1
          invs[b][invcnt[b]] = a
        elseif level[sb] == level[a] + 1 then
          invcnt[b] = invcnt[b] + 1
          invs[b][invcnt[b]] = a
        end
      else
        if lvmax == lvinf then
          lvmax = level[a]
        end
        if padded[b] then
        else
          padded[b] = true
          psize = psize + 1
          p[psize] = b
        end
        invcnt[b] = invcnt[b] + 1
        invs[b][invcnt[b]] = a
      end
    end
  end
  self.psize = psize
  return lvmax
end

HKmatch.dfs = function(self, b, lv)
  for i = 1, self.invcnt[b] do
    local a = self.invs[b][i]
    if self.level[a] == 1 or (self.level[a] == lv and self:dfs(self.dst[a], lv - 1)) then
      self.dst[a], self.src[b] = b, a
      self.level[a] = -1
      return true
    end
  end
end

HKmatch.restore = function(self, bend, lvend)
  local invs, invcnt, invpos = self.invs, self.invcnt, self.invpos
  local dst, src = self.dst, self.src
  local level = self.level
  local bn = #src
  for i = 1, bn do
    invpos[i] = 0
  end
  local accept = false
  local tasks = self.tasks
  local taskpos = 1
  tasks[1] = bend
  while 0 < taskpos do
    local b = tasks[taskpos]
    if accept then
      local a = invs[b][invpos[b]]
      dst[a], src[b] = b, a
      level[a] = -1
      taskpos = taskpos - 1
    else
      if invpos[b] == invcnt[b] then
        taskpos = taskpos - 1
      else
        local ip = invpos[b] + 1
        invpos[b] = ip
        local a = invs[b][ip]
        if level[a] == 1 then
          accept = true
          dst[a], src[b] = b, a
          level[a] = -1
          taskpos = taskpos - 1
        elseif level[a] + taskpos == lvend + 1 then
          taskpos = taskpos + 1
          tasks[taskpos] = dst[a]
        end
        -- if self.level[a] == 1 or (self.level[a] == lv and self:dfs(self.dst[a], lv - 1)) then
        --   self.dst[a], self.src[b] = b, a
        --   self.level[a] = -1
        --   return true
        -- end
      end
    end
  end
end

HKmatch.matching = function(self)
  local an = #self.dst
  local lv = self:makeAugPath()
  while lv <= an do
    for i = 1, self.psize do
      self:restore(self.p[i], lv)
      -- self:dfs(self.p[i], lv)
    end
    lv = self:makeAugPath()
  end
end

HKmatch.new = function(an, bn)
  local obj = {}
  setmetatable(obj, {__index = HKmatch})
  obj:create(an, bn)
  return obj
end

local h, w = io.read("*n", "*n", "*l")
local an, bn = 0, 0
local as, bs = {}, {}
local invidx = {}
for i = 1, h do
  for j = 1, w do
    local idx = (i - 1) * w + j
    if (i + j) % 2 == 0 then
      an = an + 1
      as[an] = idx
      invidx[idx] = an
    else
      bn = bn + 1
      bs[bn] = idx
      invidx[idx] = bn
    end
  end
end
local hkm = HKmatch.new(an, bn)
local map = {}
for i = 1, h do
  local s = io.read()
  for j = 1, w do
    local idx = (i - 1) * w + j
    map[idx] = s:sub(j, j)
  end
end
for i = 1, h - 1 do
  for j = 1, w do
    local idx = (i - 1) * w + j
    local isleft = (i + j) % 2 == 0
    if map[idx] == "." and map[idx + w] == "." then
      if isleft then
        hkm:addEdge(invidx[idx], invidx[idx + w])
      else
        hkm:addEdge(invidx[idx + w], invidx[idx])
      end
    end
  end
end
for i = 1, h do
  for j = 1, w - 1 do
    local idx = (i - 1) * w + j
    local isleft = (i + j) % 2 == 0
    if map[idx] == "." and map[idx + 1] == "." then
      if isleft then
        hkm:addEdge(invidx[idx], invidx[idx + 1])
      else
        hkm:addEdge(invidx[idx + 1], invidx[idx])
      end
    end
  end
end
hkm:matching()
local cnt = 0
for i = 1, an do
  local d = hkm.dst[i]
  if d then
    cnt = cnt + 1
    local l, r = as[i], bs[d]
    if l + w == r then
      map[l] = "v"
      map[r] = "^"
    elseif l - w == r then
      map[r] = "v"
      map[l] = "^"
    elseif l + 1 == r then
      map[l] = ">"
      map[r] = "<"
    elseif l - 1 == r then
      map[l] = "<"
      map[r] = ">"
    end
  end
end
print(cnt)
for i = 1, h do
  for j = 1, w do
    io.write(map[(i - 1) * w + j])
  end
  io.write("\n")
end