#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;
struct edge{
    int to;
    long long cap;
    int rev;
};
struct Dinic{
    int V;
    vector<int> level, used;
    vector<vector<edge>> G;
    Dinic(int N){
        V = N;
        used.resize(V, 0);
        level.resize(V, -1);
        G.resize(V);
    }
    void add(int u, int v, long long c){
        edge e1 = {v, c, (int)G[v].size()};
        G[u].push_back(e1);
        edge e2 = {u, 0, (int)G[u].size() - 1};
        G[v].push_back(e2);
    }
    void bfs(int s){
        level.assign(V, -1);
        queue<int> q;
        q.push(s);
        level[s] = 0;
        while(!q.empty()){
            int v = q.front();
            q.pop();
            for(edge e: G[v]){
                if(e.cap > 0 && level[e.to] < 0){
                    level[e.to] = level[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }
    long long dfs(int s, int t, long long f){
        if(s == t) return f;
        for(int &i = used[s]; i < (int)G[s].size(); i++){
            edge &e = G[s][i];
            if(e.cap > 0 && level[e.to] > level[s]){
                long long d = dfs(e.to, t, min(f, e.cap));
                if(d > 0){
                    e.cap -= d;
                    G[e.to][e.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }
    long long solve(int s, int t){
        long long flow = 0;
        long long INF = 1e18;
        while(1){
            bfs(s);
            if(level[t] < 0) return flow;
            used.assign(V, 0);
            long long f;
            while((f = dfs(s, t, INF)) > 0) flow += f;
        }
    }
};

int main(){
    int N, M;
    cin >> N >> M;
    vector<string> S(N);
    for(int i = 0; i < N; i++) cin >> S[i];
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
    Dinic D(N * M + 2);
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(S[i][j] == '#') continue;
            if((i + j) % 2 == 1){
                int s = i * M + j;
                D.add(N * M, s, 1);
                for(int k = 0; k < 4; k++){
                    int nx = i + dx[k], ny = j + dy[k];
                    if(0 <= nx && nx < N && 0 <= ny && ny < M && S[nx][ny] == '.'){
                        int t = nx * M + ny;
                        D.add(s, t, 1);
                    }
                }
            }
            else{
                int s = i * M + j, t = N * M + 1;
                D.add(s, t, 1);
            }
        }
    }
    int f = D.solve(N * M, N * M + 1);
    cout << f << endl;
    auto check = [&](int x, int y, int nx, int ny){
        if(x == nx && y + 1 == ny) S[x][y] = '>', S[nx][ny] = '<';
        else if(x == nx && y - 1 == ny) S[x][y] = '<', S[nx][ny] = '>';
        else if(x + 1 == nx && y == ny) S[x][y] = 'v', S[nx][ny] = '^';
        else if(x - 1 == nx && y == ny) S[x][y] = '^', S[nx][ny] = 'v';
    };
    for(int i = 0; i < N; i++){
        for(int j = 0; j < M; j++){
            if(S[i][j] == '#') continue;
            if((i + j) % 2 == 1){
                for(edge e: D.G[i * M + j]){
                    if(e.to == N * M || e.to == N * M + 1) continue;
                    if(e.cap == 0){
                        int ny = e.to % M, nx = e.to / M;
                        check(i, j, nx, ny);
                    }
                }
            }
        }
    }
    for(int i = 0; i < N; i++) cout << S[i] << endl;
}

Measured memory_bytes: 5776