// Template
#include <bits/stdc++.h>
#define rep_override(x, y, z, name, ...) name
#define rep2(i, n) for (int i = 0; i < (int)(n); ++i)
#define rep3(i, l, r) for (int i = (int)(l); i < (int)(r); ++i)
#define rep(...) rep_override(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)
#define per(i, n) for (int i = (int)(n) - 1; i >= 0; --i)
#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
constexpr int inf = 1001001001;
constexpr ll INF = 3003003003003003003LL;
template <typename T> inline bool chmin(T &x, const T &y) {if (x > y) {x = y; return 1;} return 0;}
template <typename T> inline bool chmax(T &x, const T &y) {if (x < y) {x = y; return 1;} return 0;}
struct IOSET {IOSET() {cin.tie(0); ios::sync_with_stdio(0); cout << fixed << setprecision(10);}} ioset;

template <typename T>
class Dinic {
    T inf;
    struct Edge {int to, rev; bool isrev; T cap;};
    struct Edge_ {int from, to; T flow;};
    vector<vector<Edge>> G;
    vector<int> dist, iter;
    bool bfs(int s, int t) {
        dist.assign(G.size(), -1);
        queue<int> q;
        dist[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int v = q.front();
            q.pop();
            for (Edge &e : G[v]) {
                if (dist[e.to] != -1 || e.cap == 0) continue;
                dist[e.to] = dist[v] + 1;
                q.push(e.to);
            }
        }
        return dist[t] != -1;
    }
    T dfs(int now, int t, T min_cap) {
        if (now == t) return min_cap;
        for (int &i = iter[now]; i < G[now].size(); ++i) {
            Edge &e = G[now][i];
            if (e.cap == 0 || dist[e.to] != dist[now] + 1) continue;
            T d = dfs(e.to, t, min(min_cap, e.cap));
            if (d > 0) {
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
        return 0;
    }
public:
    Dinic(int V) : G(V), inf(numeric_limits<T>::max()) {}
    void AddEdge(int from, int to, T cap) {
        G[from].push_back(Edge{to, (int)G[to].size(), false, cap});
        G[to].push_back(Edge{from, (int)G[from].size() - 1, true, 0});
    }
    T MaxFlow(int s, int t) {
        T ans = 0;
        while (bfs(s, t)) {
            iter.assign(G.size(), 0);
            T f = 0;
            while ((f = dfs(s, t, inf)) > 0) ans += f;
        }
        return ans;
    }
    vector<Edge_> edges() {
        vector<Edge_> vec;
        for (int i = 0; i < G.size(); ++i) for (Edge &e : G[i]) {
            if (!e.isrev) vec.push_back(Edge_{i, e.to, G[e.to][e.rev].cap});
        }
        return vec;
    }
};

// Main
int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<char>> grid(n, vector<char>(m));
    rep(i, n) rep(j, m) cin >> grid[i][j];
    
    Dinic<int> g(n * m + 2);
    const int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
    int s = n * m, t = n * m + 1;
    rep(i, n) rep(j, m) {
        if (grid[i][j] == '#') continue;
        if ((i + j) & 1) {
            g.AddEdge(s, i * m + j, 1);
            rep(k, 4) {
                if (i + dx[k] < 0 || i + dx[k] >= n || j + dy[k] < 0 || j + dy[k] >= m) continue;
                if (grid[i + dx[k]][j + dy[k]] == '#') continue;
                g.AddEdge(i * m + j, (i + dx[k]) * m + (j + dy[k]), 1);
            }
        } else {
            g.AddEdge(i * m + j, t, 1);
        }
    }
    
    cout << g.MaxFlow(s, t) << "\n";
    
    auto edges = g.edges();
    for (auto &e : edges) {
        if (e.from == s || e.to == t || e.flow == 0) continue;
        int i0 = e.from / m, j0 = e.from % m, i1 = e.to / m, j1 = e.to % m;
        if (i0 + 1 == i1) {
            grid[i0][j0] = 'v';
            grid[i1][j1] = '^';
        }
        if (i0 - 1 == i1) {
            grid[i0][j0] = '^';
            grid[i1][j1] = 'v';
        }
        if (j0 + 1 == j1) {
            grid[i0][j0] = '>';
            grid[i1][j1] = '<';
        }
        if (j0 - 1 == j1) {
            grid[i0][j0] = '<';
            grid[i1][j1] = '>';
        }
    }
    
    rep(i, n) {
        rep(j, m) cout << grid[i][j];
        cout << "\n";
    }
    return 0;
}


Measured memory_bytes: 5828