using namespace std;

//#define fileio

#ifndef fileio
#include <iostream>
#endif
#include <fstream>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <map>
#include <assert.h>
#include <functional>
#include <math.h>
#include <string>
#include <ctime>

typedef long long ll;

#ifdef fileio
ifstream cin;
ofstream cout;
#endif


struct dinic {
	struct edge {
		int u, v;
		ll cap, flow;
		edge() {}
		edge(int u, int v, ll cap) : u(u), v(v), cap(cap), flow(0) {}
	};

	int N;
	vector<edge> E;
	vector<vector<int>> g;
	vector<int> d, pt;

	dinic(int N) : N(N), E(0), g(N), d(N), pt(N) {}

	dinic(vector<vector<pair<int, ll>> > graph) : N(graph.size()), E(0), g(graph.size()), d(graph.size()), pt(graph.size()) {
		for (int u = 0; u < graph.size(); u++) {
			for (auto p : graph[u]) add_edge(u, p.first, p.second);
		}
	}

	void add_edge(int u, int v, ll cap) {
		if (u == v) return;
		g[u].emplace_back(E.size());
		E.emplace_back(edge(u, v, cap));
		g[v].emplace_back(E.size());
		E.emplace_back(edge(v, u, 0));
	}

	bool bfs(int S, int T) {
		fill(d.begin(), d.end(), N + 1);
		int qf = 0, qb = 1;
		d[S] = 0;
		pt[0] = S;
		while (qf != qb) {
			int u = pt[qf++];
			if (u == T) break;
			for (int k : g[u]) {
				edge& e = E[k];
				if (e.flow < e.cap && d[e.v] > d[e.u] + 1) {
					d[e.v] = d[e.u] + 1;
					pt[qb++] = e.v;
				}
			}
		}
		return d[T] != N + 1;
	}

	ll dfs(int u, int T, ll flow = -1) {
		if (u == T || !flow) return flow;
		for (int& i = pt[u]; i < g[u].size(); ++i) {
			edge& e = E[g[u][i]];
			edge& oe = E[g[u][i] ^ 1];
			if (d[e.v] == d[e.u] + 1) {
				ll amt = e.cap - e.flow;
				if (flow != -1 && amt > flow) amt = flow;
				if (ll pushed = dfs(e.v, T, amt)) {
					e.flow += pushed;
					oe.flow -= pushed;
					return pushed;
				}
			}
		}
		return 0;
	}

	ll flow(int S, int T) {
		ll tot = 0;
		while (bfs(S, T)) {
			// if using fp arithmetic, limit this to N passes explicitly
			fill(pt.begin(), pt.end(), 0);
			while (ll flow = dfs(S, T))
				tot += flow;
		}
		return tot;
	}
};


int main() {
	ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#ifdef fileio
	cin.open("Text.txt");
	cout.open("Output.txt");
#endif
	int n;
	int m;
	cin >> n >> m;
	dinic d(n * m + 2);
	vector<string> v;
	for (int i = 0; i < n; i++) {
		string s;
		cin >> s;
		v.push_back(s);
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			if (v[i][j] == '.') {
				if ((i + j) % 2 == 0)
					d.add_edge(0, i * m + j + 1, 1);
				else
					d.add_edge(i * m + j + 1, n * m + 1, 1);
				if (i > 0 && v[i - 1][j] == '.') {
					if ((i + j) % 2 == 0)
						d.add_edge(i * m + j + 1, (i - 1) * m + j + 1, 1);
					else
						d.add_edge((i - 1) * m + j + 1, i * m + j + 1, 1);
				}
				if (j > 0 && v[i][j - 1] == '.') {
					if ((i + j) % 2 == 0)
						d.add_edge(i * m + j + 1, i * m + j - 1 + 1, 1);
					else
						d.add_edge(i * m + j - 1 + 1, i * m + j + 1, 1);
				}
			}

		}
	}
	cout << d.flow(0, n * m + 1) << endl;
	for (auto e : d.E) {
		if (e.u > 0 && e.u <= n * m && e.v > 0 && e.v <= n * m && e.flow == 1) {
			int i1 = (e.u - 1) / m;
			int j1 = (e.u - 1) % m;
			int i2 = (e.v - 1) / m;
			int j2 = (e.v - 1) % m;
			if (i1 < i2) {
				v[i1][j1] = 'v';
				v[i2][j2] = '^';
			}
			if (i1 > i2) {
				v[i1][j1] = '^';
				v[i2][j2] = 'v';
			}
			if (j1 < j2) {
				v[i1][j1] = '>';
				v[i2][j2] = '<';
			}
			if (j1 > j2) {
				v[i1][j1] = '<';
				v[i2][j2] = '>';
			}
		}
	}

	for (int i = 0; i < v.size(); i++) {
		cout << v[i] << endl;
	}


}





Measured memory_bytes: 5468