#define _DEBUG
//ヘッダー
#include<bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;

//型定義
typedef long long ll;

//定数
const ll INF=1e+18;
const int MOD=1e+9+7;

//デバッグ
#define CHOOSE(a) CHOOSE2 a
#define CHOOSE2(a0,a1,a2,a3,a4,x,...) x
#define debug1(x1) cout<<#x1<<": "<<x1<<endl
#define debug2(x1,x2) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<endl
#define debug3(x1,x2,x3) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<endl
#define debug4(x1,x2,x3,x4) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<endl
#define debug5(x1,x2,x3,x4,x5) cout<<#x1<<": "<<x1<<", "#x2<<": "<<x2<<", "#x3<<": "<<x3<<", "#x4<<": "<<x4<<", "#x5<<": "<<x5<<endl
#ifdef _DEBUG
#define debug(...) CHOOSE((__VA_ARGS__,debug5,debug4,debug3,debug2,debug1,~))(__VA_ARGS__)
#else
#define debug(...)
#endif

//REPマクロ
#define REP(i,n) for(ll i=0;i<(ll)(n);i++)
#define REPD(i,n) for(ll i=n-1;i>=0;i--)
#define REP2(i,a,b) for(ll i=a;i<(ll)(b);i++)
#define REPD2(i,a,b) for(ll i=a;i>(ll)(b);i--)

// 多次元 vector 生成
template<class T>
vector<T> make_vec(size_t a){
    return vector<T>(a);
}
template<class T, class... Ts>
auto make_vec(size_t a, Ts... ts){
  return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}

//vectorの扱い
#define ALL(x) (x).begin(),(x).end() //sortなどの引数省略
#define SIZE(x) ((ll)(x).size()) //size
#define MAX(x) *max_element(ALL(x)) //最大値
#define MIN(x) *min_element(ALL(x)) //最小値

//省略
using vi  = vector<int>;
using vii = vector<vector<int>>;
using vl  = vector<ll>;
using vll = vector<vector<ll>>;
using pii = pair<int,int>;
using pll = pair<ll,ll>;

const vector<pii> dG = {{-1,0},{1,0},{0,-1},{0,1}};

int main(){
    int N,M;
    cin>>N>>M;
    mf_graph<int> G(N*M+2);
    vector<vector<char>> MAP(N,vector<char>(M,'#'));

    REP(i,N){
        string S;
        cin>>S;
        REP(j,M){
            MAP[i][j]=S[j];
        }
    }

    int s=M*N;
    int g=M*N+1;

    //s->odd even->g
    REP(i,N){
        REP(j,M){
            if(MAP[i][j]=='#') continue;
            int v=i*M+j;
            if((i+j)%2==1){
                G.add_edge(s,v,1);
            }else{
                G.add_edge(v,g,1);
            }
        }
    }

    //odd->even
    REP(i,N){
        REP(j,M){
            int v=M*i+j;
            if((i+j)%2==0) continue;
            if(MAP[i][j]=='#') continue;
            for(auto dv:dG){
                int idx=i+dv.first;
                int jdx=j+dv.second;

                if(idx>=N||idx<0) continue;
                if(jdx>=M||jdx<0) continue;
                
                if(MAP[idx][jdx]=='#') continue;
                int nv=M*idx+jdx;
                G.add_edge(v,nv,1);
            }
        }
    }
    
    cout<<G.flow(s,g)<<endl;

    for(auto edge:G.edges()){
        
        int from=edge.from;
        int to=edge.to;
        int flow=edge.flow;

        if(from==s||to==g||flow==0) continue;

        int i_from=from/M;
        int j_from=from%M;
        int i_to=to/M;
        int j_to=to%M;

        if(i_to==i_from+1){
            MAP[i_from][j_from]='v';
            MAP[i_to][j_to]='^';
        }else if(i_to==i_from-1){
            MAP[i_from][j_from]='^';
            MAP[i_to][j_to]='v';
        }else if(j_to==j_from+1){
            MAP[i_from][j_from]='>';
            MAP[i_to][j_to]='<';
        }else{
            MAP[i_from][j_from]='<';
            MAP[i_to][j_to]='>';
        }
    }

    REP(i,N){
        REP(j,M){
            cout<<MAP[i][j];
        }
        cout<<endl;
    }


}

Measured memory_bytes: 5520