#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(ll i=0;i<n;i++)
#define repl(i,l,r) for(ll i=(l);i<(r);i++)
#define per(i,n) for(ll i=n-1;i>=0;i--)
#define perl(i,r,l) for(ll i=r-1;i>=l;i--)
#define fi first
#define se second
#define pb push_back
#define ins insert
#define pqueue(x) priority_queue<x,vector<x>,greater<x>>
#define all(x) (x).begin(),(x).end()
#define CST(x) cout<<fixed<<setprecision(x)
#define rev(x) reverse(x);
using ll=long long;
using vl=vector<ll>;
using vvl=vector<vector<ll>>;
using pl=pair<ll,ll>;
using vpl=vector<pl>;
using vvpl=vector<vpl>;
const ll MOD=1000000007;
const ll MOD9=998244353;
const int inf=1e9+10;
const ll INF=4e18;
const ll dy[9]={1,0,-1,0,1,1,-1,-1,0};
const ll dx[9]={0,-1,0,1,1,-1,1,-1,0};
template<class T> inline bool chmin(T& a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

 
struct Dinic {
  struct edge {
    int to, cap, rever;
    bool inv;
    edge(int to, int cap, int rever, bool inv):to(to), cap(cap), rever(rever), inv(inv){}
  };
  vector< vector<edge> > graph;
  vector<int> level, iter;
  Dinic(int V):graph(V), level(V), iter(V){}
  void add_edge(int from, int to, int cap) {
    graph[from].emplace_back(to, cap, graph[to].size(),0);
    graph[to].emplace_back(from, 0, graph[from].size()-1,1);
  }
  void bfs(int s) {
    fill(all(level), -1);
    queue<int> que;
    level[s] = 0;
    que.push(0);
    while(que.size()) {
      int v = que.front(); que.pop();
      for(edge& e : graph[v]) {
        if(e.cap > 0 && level[e.to] < 0) {
          level[e.to] = level[v] + 1;
          que.push(e.to);
        }
      }
    }
  }
  int dfs(int v, int t, int f) {
    if(v == t) return f;
    for(int& i = iter[v]; i < graph[v].size(); i++) {
      edge& e = graph[v][i];
      if(e.cap > 0 && level[v] < level[e.to]) {
        int d = dfs(e.to, t, min(e.cap, f));
        if(d > 0) {
          e.cap -= d;
          graph[e.to][e.rever].cap += d;
          return d;
        }
      }
    }
    return 0;
  }
  int max_flow(int s, int t) {
    int flow = 0;
    while(true) {
      bfs(s);
      if(level[t] < 0) return flow;
      fill(all(iter), 0);
      int f; while((f = dfs(s, t, inf)) > 0) flow += f;
    }
  }
}; 


int main(){
    ll h,w;cin >> h >>w;
    Dinic dn(h*w+2);
    vector<string> g(h);rep(i,h)cin >> g[i];
    ll s=0,t=h*w+1;
    rep(i,h){
        rep(j,w){
            if(g[i][j]=='#')continue;
            if((i+j)%2){
                dn.add_edge(s,i*w+j+1,1);
            }
            else{
                dn.add_edge(i*w+j+1,t,1);
                rep(k,4){
                    ll nx=i+dx[k],ny=j+dy[k];
                    if(nx<0||ny<0||nx>=h||ny>=w)continue;
                    if(g[nx][ny]=='#')continue;
                    dn.add_edge(nx*w+ny+1,i*w+j+1,1);
                }
            }
        }
    }
    cout << dn.max_flow(s,t) <<endl;

    rep(i,h*w+2){
        for(auto e:dn.graph[i]){
            if(!e.inv&&e.cap==0&&i!=0&&e.to!=h*w+1){
                ll a=i,b=e.to;
                a--;b--;if(a>b)swap(a,b);
                if(a/w!=b/w){
                    g[a/w][a%w]='v';g[b/w][b%w]='^';
                }
                else{
                    g[a/w][a%w]='>';g[b/w][b%w]='<';
                }
            }
        }
    }
    rep(i,h){
        rep(j,w){
            cout << g[i][j];
        }
        cout << endl;
    }
}

Measured memory_bytes: 5168