#pragma GCC target ("avx2")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize ("O3")
#include "bits/stdc++.h"
#include <unordered_set>
#include <unordered_map>
#include <random>
using namespace std;
typedef long long ll;
const ll MOD = 1'000'000'007LL; /*998'244'353LL;*/
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for(int (i)=0; (i)<(n); (i)++)
const int dx[4]={ 1,0,-1,0 };
const int dy[4]={ 0,1,0,-1 };

struct MaxFlow{
private:
    struct edge{ int to, cap, rev, num; bool isrev; };

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

public:
    vector<int> edges;

    MaxFlow(int _V=0){
        V = _V;
        G.resize(V);
        used.resize(V);
    }

    void add(int from, int to, int cap){
        G[from].push_back({ to, cap, (int)G[to].size(),(int)edges.size(),false });
        G[to].push_back({ from, 0, (int)G[from].size()-1,(int)edges.size(),true });
        edges.push_back(0);
    }

    int dfs(int v, int t, int f){
        if(v == t) return f;
        used[v] = true;
        for(int i=0; i<G[v].size(); i++){
            edge& e = G[v][i];
            if(!used[e.to] && e.cap > 0){
                int d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    if(!e.isrev) edges[e.num] += d;
                    else edges[e.num] -= d;
                    return d;
                }
            }
        }
        return 0;
    }

    int calculate(int s, int t){
        int ret = 0;
        while(true){
            used.assign(V, false);
            int f = dfs(s, t, INT_MAX);
            if(f == 0) break;
            ret += f;
        }
        return ret;
    }
};

int H, W;
string S[100];

signed main(){
    cin >> H >> W;
    rep(i, H) cin >> S[i];

    MaxFlow f(1 + H*W + (W-1)*H + W*(H-1) + 1);
    rep(i, H){
        rep(j, W-1){
            if((i+j)%2 == 0){
                f.add(1 + H*W + (W-1)*i+j, 1 + W*i + j+1, 1);
            }
            else{
                f.add(1 + H*W + (W-1)*i+j, 1 + W*i + j, 1);
            }
        }
    }
    rep(i, H-1){
        rep(j, W){
            if((i+j)%2 == 0){
                f.add(1 + H*W + (W-1)*H + W*i+j, 1 + W*(i+1) + j, 1);
            }
            else{
                f.add(1 + H*W + (W-1)*H + W*i+j, 1 + W*i + j, 1);
            }
        }
    }
    rep(i, H){
        rep(j, W-1){
            if((i+j)%2 == 0){
                f.add(1 + W*i + j, 1 + H*W + (W-1)*i+j, 1);
            }
            else{
                f.add(1 + W*i + j+1, 1 + H*W + (W-1)*i+j, 1);
            }
        }
    }
    rep(i, H-1){
        rep(j, W){
            if((i+j)%2 == 0){
                f.add(1 + W*i + j, 1 + H*W + (W-1)*H + W*i+j, 1);
            }
            else{
                f.add(1 + W*(i+1) + j, 1 + H*W + (W-1)*H + W*i+j, 1);
            }
        }
    }
    rep(i, H){
        rep(j, W){
            if((i+j)%2 == 0){
                if(S[i][j] != '#') f.add(0, 1 + W*i + j, 1);
            }
            else{
                if(S[i][j] != '#') f.add(1 + W*i + j, 1 + H*W + (W-1)*H + W*(H-1), 1);
            }
        }
    }

    cout << f.calculate(0, 1 + H*W + (W-1)*H + W*(H-1)) << endl;
    int k = 0;
    rep(i, H){
        rep(j, W-1){
            if(f.edges[k] > 0){
                S[i][j] = '>';
                S[i][j+1] = '<';
            }
            k++;
        }
    }
    rep(i, H-1){
        rep(j, W){
            if(f.edges[k] > 0){
                S[i][j] = 'v';
                S[i+1][j] = '^';
            }
            k++;
        }
    }
    rep(i, H) cout << S[i] << endl;
}

Measured memory_bytes: 8872