#include <bits/stdc++.h>
#define GetAns(from, to, flag) a[from / M][from % M] = chr[flag][0], a[to / M][to % M] = chr[flag][1]
using namespace std;

const int inf = 0x3f3f3f3f;

struct edge {
	int to, cap;
	char flag; // 0: r -> l   1: u -> d
	edge(): flag(-1) {}
	edge(const int &t, const int &c, const char &f): to(t), cap(c), flag(f) {}
} ge[60000];
int n, m;
vector <int> gl[10010];
int depth[10010], q[10010];
int iter[10010];

int N, M;
char a[110][110];
char dir[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 };
char chr[4][2] = { 'v', '^', '>' , '<', '^', 'v', '<', '>' };
void AddEdge(const int &from, const int &to, const int &cap, const char &flag);
int MaxFlow(const int &from, const int &to);
int dfs(const int &from, const int &to, const int &flow);

int main() {
	scanf("%d%d", &N, &M);
	const int s = N * M, t = N * M + 1;
	for (int i = 0; i < N; ++i)
		scanf("%s", a[i]);

	for (int i = 0; i < N; ++i)
		for (int j = i & 1; j < M; j += 2)
			if (a[i][j] == '.') {
				if (i + 1 < N && a[i + 1][j] == '.')
					AddEdge(i * M + j, (i + 1) * M + j, 1, 0);
				if (j + 1 < M && a[i][j + 1] == '.')
					AddEdge(i * M + j, i * M + j + 1, 1, 1);
				if (i > 0 && a[i - 1][j] == '.')
					AddEdge(i * M + j, (i - 1) * M + j, 1, 2);
				if (j > 0 && a[i][j - 1] == '.')
					AddEdge(i * M + j, i * M + j - 1, 1, 3);
			}
	for (int i = 0; i < N; ++i)
		for (int j = 0; j < M; ++j)
			if (a[i][j] == '.')
				if (i + j & 1)
					AddEdge(i * M + j, t, a[i][j] == '.', -1);
				else
					AddEdge(s, i * M + j, a[i][j] == '.', -1);
	printf("%d\n", MaxFlow(s, t));

	for (int i = 0; ge[i].flag != -1; i += 2)
		if (!ge[i].cap)
			GetAns(ge[i ^ 1].to, ge[i].to, ge[i].flag);
	for (int i = 0; i < N; ++i)
		printf("%s\n", a[i]);
	return 0;
}


void AddEdge(const int &from, const int &to, const int &cap, const char &flag) {
	ge[m] = edge(to, cap, flag);
	gl[from].push_back(m++);
	ge[m] = edge(from, 0, -1);
	gl[to].push_back(m++);
}

int MaxFlow(const int &from, const int &to) {
	int flow = 0;
	while (true) {
		memset(depth, -1, sizeof(depth));
		depth[from] = 0;
		int h = 0, t = 1; q[h] = from;
		while (h < t) {
			int u = q[h++];
			for (int i = 0; i < gl[u].size(); ++i) {
				edge &e = ge[gl[u][i]];
				if (e.cap > 0 && depth[e.to] == -1)
					q[t++] = e.to, depth[e.to] = depth[u] + 1;
			}
		}
		if (depth[to] == -1)
			return flow;

		memset(iter, 0, sizeof(iter));
		int f;
		while (f = dfs(from, to, inf))
			flow += f;
	}
}

int dfs(const int &from, const int &to, const int &flow) {
	if (from == to)
		return flow;
	for (int &i = iter[from]; i < gl[from].size(); ++i) {
		edge &e = ge[gl[from][i]], &e1 = ge[gl[from][i] ^ 1];
		if (e.cap > 0 && depth[e.to] == depth[from] + 1) {
			int f = dfs(e.to, to, min(flow, e.cap));
			if (f) {
				e.cap -= f;
				e1.cap += f;
				return f;
			}
		}
	}
	return 0;
}

