#include <iostream>
#include <string>
#include <sstream>
#include <iomanip> 
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <complex>

using namespace std;

#pragma GCC optimize("Ofast")
#pragma GCC optimization("unroll-loops, no-stack-protector")
#pragma GCC target("avx,avx2,fma")




class min_cost_flow {		
public:

	struct edge_node {
		int to;
		int capacity, flow;
		int cost;
		int reverse_id;
	};

	int VERYBIG = 2E9;
	bool min_cost_needed;			// whether min cost calculation is needed
	int n, f, mf, totalcost;
	int s, t;		// source and sink
	vector<vector<edge_node>> adj; 
	vector<int> pp, ppid;

	min_cost_flow(int nn, int start, int terminal) {		// initialize network with n nodes, starting from 0
		n = nn;
		s = start;
		t = terminal;

		adj.clear();
		adj.resize(nn);
	}


	void add_path(int a, int b, int forward_capacity, int backward_capacity = 0, int forward_cost = 0, int backward_cost = 0) {	// one directional
		int ida = adj[a].size(), idb = adj[b].size();
		adj[a].push_back({ b, forward_capacity, 0, forward_cost, idb });
		adj[b].push_back({ a, backward_capacity, 0, backward_cost, ida });
	}

	void clear_flow() {		// reset all flow to zero from network 
		int i;
		for (i = 0; i < n; i++) {
			for (auto p : adj[i]) p.flow = 0;
		}
	}

	void augment(int v, int maxflow) {
		if (v == s) {
			f = maxflow;		// external variable
		}
		else if (pp[v] != -1) {
			int parent = pp[v], pid = ppid[v], rid = adj[parent][pid].reverse_id;
			int available_flow = adj[parent][pid].capacity - adj[parent][pid].flow;

			if (maxflow < available_flow) augment(parent, maxflow);
			else augment(parent, available_flow); 

			adj[parent][pid].flow += f;
			adj[v][rid].flow -= f;

			totalcost += f * (adj[parent][pid].cost - adj[v][rid].cost);
		}
	}

	void solve_flow() {		// returns total cost and mf
		mf = 0;
		totalcost = 0;

		while (1) {
			int i, j, k;
			vector<int> dist, mincost;
			dist.assign(n, VERYBIG);
			dist[s] = 0;

			queue<int> q;
			q.push(s);

			pp.assign(n, -1);		// point back to parents
			ppid.assign(n, -1);		// point back to the edge id in parents

			while (!q.empty()) {
				int u = q.front(), v;
				q.pop();
				for (i = 0; i < adj[u].size(); i++) {
					v = adj[u][i].to;
					if ((adj[u][i].flow < adj[u][i].capacity) && (dist[v] > dist[u] + adj[u][i].cost)) {
						dist[v] = dist[u] + adj[u][i].cost;
						q.push(v);
						pp[v] = u;
						ppid[v] = i;
					}
				}
			}

			f = 0;
			augment(t, VERYBIG);
			if (f == 0) break;
			if (f == VERYBIG) break;
			mf += f;

			//totalcost /= 2;
		}

	}
};



int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);

	int n, m, i, j, k, ans, x, y, xx, yy, id;

	cin >> n >> m;
	vector<string> s(n);
	for (i = 0; i < n; i++) cin >> s[i];

	min_cost_flow fl(n * m + 2, 0, n * m + 1);
	for (i = 0; i < n; i++) {
		for (j = 0; j < m; j++) {
			if (s[i][j] == '#') continue;

			if ((i + j) % 2 == 0) {
				fl.add_path(0, i * m + j + 1, 1);
				if ((j < m - 1) && (s[i][j + 1] == '.')) fl.add_path(i * m + j + 1, i * m + j + 2, 1, 0);
				if ((i < n - 1) && (s[i + 1][j] == '.')) fl.add_path(i * m + j + 1, i * m + j + 1 + m, 1, 0);
				if ((j > 0) && (s[i][j - 1] == '.')) fl.add_path(i * m + j + 1, i * m + j, 1, 0);
				if ((i > 0) && (s[i - 1][j] == '.')) fl.add_path(i * m + j + 1, i * m + j + 1 - m, 1, 0);
			}
			else fl.add_path(i * m + j + 1, n * m + 1, 1);

		}
	}

	fl.solve_flow();
	ans = fl.mf;
	for (i = 0; i < n; i++) {
		for (j = 0; j < m; j++) {
			if (s[i][j] == '#') continue;

			id = i * m + j + 1;
			for (auto p : fl.adj[id]) {
				if ((i + j) % 2 == 1) continue;

				if ((j < m - 1) && (s[i][j + 1] == '.') && (p.to == id + 1) && (p.flow != 0)) {
					s[i][j] = '>';
					s[i][j + 1] = '<';
				}
				if ((i < n - 1) && (s[i + 1][j] == '.') && (p.to == id + m) && (p.flow != 0)) {
					s[i][j] = 'v';
					s[i + 1][j] = '^';
				}
				if ((j > 0) && (s[i][j - 1] == '.') && (p.to == id - 1) && (p.flow != 0)) {
					s[i][j] = '<';
					s[i][j - 1] = '>';
				}
				if ((i > 0) && (s[i - 1][j] == '.') && (p.to == id - m) && (p.flow != 0)) {
					s[i][j] = '^';
					s[i - 1][j] = 'v';
				}
			}
		}
	}


	cout << ans << "\n";
	for (auto p : s) cout << p << "\n";


return 0;
}


Measured memory_bytes: 5472