// #pragma GCC optimize("Ofast,unroll-loops,inline,fast-math")
// #pragma GCC target("avx,avx2,fma")
/*__stO_stO_stO_stO_stO_stO_stO_zit_Orz_Orz_Orz_Orz_Orz_Orz_Orz__*/
#include<bits/stdc++.h>
using namespace std;
#define name "zit"
using ll = int ;const ll MOD2=998244353;
#define all(x,y) x.begin()+1, x.begin()+y+1
#define FOR(i,a,b) for(ll i=(a);i<=(b);++i)
using vl=vector<ll>; using pll=pair<ll,ll>;
const int maxn=5e6+1, MOD=1e9+7;// __ c:|
#define pb push_back// zit#6421 <(o )____|
const long long INF = 2e18;ll n;//( ._> /|
#define All(x) x.begin(),x.end()/* `----'*/
#define stop assert(0||!(cerr<<"\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"));
#define ok cerr << "if u see this line , then ur code worked orz\n"
#define pr(orz) copy(orz,ostream_iterator<ll>(cerr," "));cerr<<'\n'
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
#define el cerr<<'\n'
vector <pll> num_pos (maxn + 5);
ll m;
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, 1, -1};
bool valid (ll x, ll y) {
return 1 <= x && x <= n && 1 <= y && y <= m;
}
struct EDge {
ll v, w;
}; vector <EDge> adj[maxn];
struct Node {
ll u, spu;
bool operator<(const Node & a) const {
return spu > a.spu;
}
};
vl trace (maxn, 0);
void dicha (ll start, vl & sp) {
FOR (i,1,maxn - 1) sp[i] = INF;
sp[start] = 0;
priority_queue <Node> q;
q.push ({start, 0});
for (;q.size ();) {
ll u = q.top ().u, spu = q.top ().spu; q.pop ();
if (spu != sp[u]) continue;
for (auto & x : adj[u]) {
ll v = x.v, w = x.w;
ll nspv = spu + w;
if (nspv < sp[v]) {
trace[v] = u;
sp[v] = nspv;
q.push ({v, sp[v]});
}
}
}
}
string moves = "^v><";
void Trace (pll start_pos, pll end_pos, vector <vector<char> > & mat, vector <vl> & num_node) {
ll x = end_pos.first, y = end_pos.second;
// debug (start_pos.first);
// debug (start_pos.second);
while (x != start_pos.first || y != start_pos.second) {
ll u = num_node[x][y];
ll t = trace[u];
pll v = num_pos[t];
// debug (v.first);
// debug (v.second);
// el;
char change = '#';
FOR (i,0,3) {
if (v.first + dx[i] == x && v.second + dy[i] == y) {
if (moves[i] != mat[v.first][v.second])
change = moves[i];
break;
}
}
if (change != '#') mat[v.first][v.second] = change;
x = v.first;
y = v.second;
}
}
void sibidi () { cin >> n;
cin >> m;
vector <vector <char> > mat (n + 1, vector <char> (m + 1));
vector <vl> num_node (n + 1, vl (m + 1, 0));
ll tot_node = 0;
pll start_pos, end_pos;
FOR (i,1,n)
FOR (j,1,m) {
cin >> mat[i][j];
num_node[i][j] = ++tot_node;
num_pos[tot_node] = {i, j};
if (mat[i][j] == 'o') start_pos = {i, j};
if (mat[i][j] == 'x') end_pos = {i, j};
}
FOR (i,1,n) {
FOR (j,1,m) {
FOR (ad,0,3) {
ll x1 = i + dx[ad], y1 = j + dy[ad];
if (!valid (x1, y1)) continue;
ll w = 1;
if (moves[ad] == mat[i][j] || mat[i][j] == 'o') {
w = 0;
}
// weight[num_node[i][j]][num_node[x1][y1]] = w;
adj[num_node[i][j]].pb ({num_node[x1][y1], w});
// adj[num_node[x1][y1]].pb ({num_node[i][j], w});
}
}
}
vl sp (maxn, INF), spn (maxn, INF);
dicha (num_node[start_pos.first][start_pos.second], sp);
// dicha (num_node[end_pos.first][end_pos.second])
ll ans = sp[num_node[end_pos.first][end_pos.second]];
cout << ans << '\n';
Trace (start_pos, end_pos, mat, num_node);
mat[start_pos.first][start_pos.second] = 'o';
FOR (i,1,n) {
FOR (j,1,m)
cout << mat[i][j];
cout << '\n';
}
} signed main() {
if(fopen(name".inp","r"))
{freopen(name".inp","r",stdin);freopen(name".out","w",stdout);}
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);ll _=1;
//cin>>_;
while(_--)sibidi();return 0;}