//#include "bits/stdc++.h"

#define _USE_MATH_DEFINES
#include<cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <deque>
#include <algorithm>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <unordered_map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <iterator>
#include<iomanip>
#include<complex>

using namespace std;

#define rep(i,a,b) for(int i=(a), i##_len=(b);i<i##_len;i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)

#define int ll
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair

//typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, double> pid;
typedef pair<double, int> pdi;
typedef pair<double, double> pdd;
typedef vector< vector<int> > mat;

template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;

const double EPS = 1e-9;

struct edge
{
	int s, t, c, rev;
	edge(int s, int t, int c, int rev) :s(s), t(t), c(c), rev(rev) {}
	edge() { s = -1, t = -1, c = -1, rev = -1; }
};

vector<vector<edge>> G;
vector<bool> used;

int dfs(int v, int t, int f)
{
	if (v == t)
	{
		return f;
	}
	used[v] = true;
	rep(i, 0, SZ(G[v]))
	{
		edge& e = G[v][i];
		if (used[e.t] || e.c == 0)
		{
			continue;
		}
		int d = dfs(e.t, t, min(f, e.c));
		if (d > 0)
		{
			e.c -= d;
			G[e.t][e.rev].c += d;
			return d;
		}
	}
	return 0;
}

int max_flow(int s, int t)
{
	int ans = 0;
	while (true)
	{
		rep(i, 0, SZ(used))used[i] = false;
		int tans = dfs(s, t, INF);
		if (tans == 0)
		{
			return ans;
		}
		ans += tans;
	}
}

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

	int N, M;
	cin >> N >> M;

	int V = N * M;
	G.resize(2 * V + 2);
	used = vector<bool>(2 * V + 2, false);

	vector<string> smap(N);
	rep(i, 0, N)cin >> smap[i];

	static const int dx[] = { 0,1,0,-1 }, dy[] = { 1,0,-1,0 };
	rep(i, 0, N)rep(j, 0, M)
	{
		if ((i + j) % 2 == 1)continue;
		if (smap[i][j] == '#')continue;
		rep(k, 0, 4)
		{
			int ni = i + dy[k], nj = j + dx[k];
			if (0 <= ni && ni < N && 0 <= nj && nj < M&&smap[ni][nj] == '.')
			{
				int s = i * M + j, t = V + ni * M + nj;
				G[s].push_back(edge(s, t, 1, SZ(G[t])));
				G[t].push_back(edge(t, s, 0, SZ(G[s]) - 1));
			}
		}
	}

	rep(i, 0, V)
	{
		G[2 * V].push_back(edge(2 * V, i, 1, SZ(G[i])));
		G[i].push_back(edge(i, 2 * V, 0, SZ(G[2 * V]) - 1));
		G[V + i].push_back(edge(V + i, 2 * V + 1, 1, SZ(G[2 * V + 1])));
		G[2 * V + 1].push_back(edge(2 * V + 1, V + i, 0, SZ(G[V + i]) - 1));
	}

	int ans = max_flow(2 * V, 2 * V + 1);

	rep(i, 0, V)
	{
		for (auto e : G[i])
		{
			if (e.s < e.t&&e.t != 2 * V&&e.c == 0)
			{
				e.t -= V;
				int sx, sy, tx, ty;
				sx = e.s%M, sy = e.s / M;
				tx = e.t%M, ty = e.t / M;
				if (sx == tx)
				{
					if (sy > ty)swap(sy, ty);
					smap[sy][sx] = 'v';
					smap[ty][tx] = '^';
				}
				else
				{
					if (sx > tx)swap(sx, tx);
					smap[sy][sx] = '>';
					smap[ty][tx] = '<';
				}
			}
		}
	}

	cout << ans << endl;
	rep(i, 0, N)
	{
		cout << smap[i] << endl;
	}


	return 0;
}

Measured memory_bytes: 7880