Buggy python submission (verdict: Runtime Error):
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 = map(int, readline().split())
S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')

A = []
B = []
E = []

for i, j in itertools.product(range(N), 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)
for key, item in 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))


Fixed submission:
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 = map(int, readline().split())
S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')

G = nx.DiGraph()
G.add_nodes_from(['S', 'T'])
for i, j in itertools.product(range(N), range(M)):
    if S[i, j] == '#':
        continue
    if (i + j) % 2 == 0:
        G.add_edge('S', (i, j), capacity=1)
    else:
        G.add_edge((i, j), 'T', capacity=1)
    if (i + j) % 2 == 0:
        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] != '#':
                G.add_edge((i, j), (i1, j1), capacity=1)

flow_value, flow = nx.maximum_flow(G, 'S', 'T')
for i, j in itertools.product(range(N), range(M)):
    if (i, j) in flow:
        for v, f in flow[(i, j)].items():
            if v == 'T' or f == 0:
                continue
            i1, j1 = v
            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(flow_value)
for row in S:
    print(''.join(row))

Buggy python submission (verdict: Runtime Error):
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 = map(int, readline().split())
S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')

A = []
B = []
E = []

for i, j in itertools.product(range(N), 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.hopcroft_karp_matching(G)
for key, item in 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))


Fixed submission:
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 = map(int, readline().split())
S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')

G = nx.DiGraph()
G.add_nodes_from(['S', 'T'])
for i, j in itertools.product(range(N), range(M)):
    if S[i, j] == '#':
        continue
    if (i + j) % 2 == 0:
        G.add_edge('S', (i, j), capacity=1)
    else:
        G.add_edge((i, j), 'T', capacity=1)
    if (i + j) % 2 == 0:
        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] != '#':
                G.add_edge((i, j), (i1, j1), capacity=1)

flow_value, flow = nx.maximum_flow(G, 'S', 'T')
for i, j in itertools.product(range(N), range(M)):
    if (i, j) in flow:
        for v, f in flow[(i, j)].items():
            if v == 'T' or f == 0:
                continue
            i1, j1 = v
            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(flow_value)
for row in S:
    print(''.join(row))

Buggy python submission (verdict: Runtime Error):
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 = map(int, readline().split())
S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')

A = []
B = []
E = []

for i, j in itertools.product(range(N), 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)
for key, item in 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))

Fixed submission:
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 = map(int, readline().split())
S = np.frombuffer(read(), 'S1').reshape(N, -1)[:, :M].astype('U1')

G = nx.DiGraph()
G.add_nodes_from(['S', 'T'])
for i, j in itertools.product(range(N), range(M)):
    if S[i, j] == '#':
        continue
    if (i + j) % 2 == 0:
        G.add_edge('S', (i, j), capacity=1)
    else:
        G.add_edge((i, j), 'T', capacity=1)
    if (i + j) % 2 == 0:
        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] != '#':
                G.add_edge((i, j), (i1, j1), capacity=1)

flow_value, flow = nx.maximum_flow(G, 'S', 'T')
for i, j in itertools.product(range(N), range(M)):
    if (i, j) in flow:
        for v, f in flow[(i, j)].items():
            if v == 'T' or f == 0:
                continue
            i1, j1 = v
            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(flow_value)
for row in S:
    print(''.join(row))