#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007;
// const int MOD = 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
const int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
  IOSetup() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
  }
} iosetup;

struct HopcroftKarp {
  vector<int> match;

  HopcroftKarp(int left, int right) : left(left), graph(left), match(left + right, -1), level(left), used(left, -1) {}

  void add_edge(int u, int v) { graph[u].emplace_back(left + v); }

  int solve() {
    int res = 0;
    while (true) {
      bfs();
      int tmp = 0;
      REP(i, left) {
        if (match[i] == -1) {
          if (dfs(i)) ++tmp;
          ++timestamp;
        }
      }
      if (tmp == 0) return res;
      res += tmp;
    }
  }

private:
  int left, timestamp = 0;
  vector<vector<int>> graph;
  vector<int> level, used;

  void bfs() {
    fill(ALL(level), -1);
    queue<int> que;
    REP(i, left) {
      if (match[i] == -1) {
        que.emplace(i);
        level[i] = 0;
      }
    }
    while (!que.empty()) {
      int ver = que.front(); que.pop();
      for (int e : graph[ver]) {
        if (match[e] != -1 && level[match[e]] == -1) {
          level[match[e]] = level[ver] + 1;
          que.emplace(match[e]);
        }
      }
    }
  }

  bool dfs(int ver) {
    used[ver] = timestamp;
    for (int e : graph[ver]) {
      int tmp = match[e];
      if (tmp == -1 || (used[tmp] < timestamp && level[tmp] == level[ver] + 1 && dfs(tmp))) {
        used[ver] = timestamp;
        match[e] = ver;
        match[ver] = e;
        return true;
      }
    }
    return false;
  }
};

int main() {
  int n, m; cin >> n >> m;
  vector<string> s(n); REP(i, n) cin >> s[i];
  vector idx(n, vector(m, 0));
  int l = 0, r = 0;
  vector<int> ly, lx, ry, rx;
  REP(i, n) REP(j, m) {
    if ((i + j) & 1) {
      idx[i][j] = r++;
      ry.emplace_back(i);
      rx.emplace_back(j);
    } else {
      idx[i][j] = l++;
      ly.emplace_back(i);
      lx.emplace_back(j);
    }
  }
  HopcroftKarp hk(l, r);
  REP(i, n) REP(j, m) {
    if (s[i][j] == '#') continue;
    int x = idx[i][j];
    if (i + 1 < n && s[i + 1][j] == '.') {
      int y = idx[i + 1][j];
      if ((i + j) % 2 == 0) {
        hk.add_edge(x, y);
      } else {
        hk.add_edge(y, x);
      }
    }
    if (j + 1 < m && s[i][j + 1] == '.') {
      int y = idx[i][j + 1];
      if ((i + j) % 2 == 0) {
        hk.add_edge(x, y);
      } else {
        hk.add_edge(y, x);
      }
    }
  }
  cout << hk.solve() << '\n';
  vector<string> t = s;
  REP(i, l) {
    if (hk.match[i] == -1) continue;
    int y1 = ly[i], x1 = lx[i], y2 = ry[hk.match[i] - l], x2 = rx[hk.match[i] - l];
    if (y1 > y2) swap(y1, y2);
    if (x1 > x2) swap(x1, x2);
    if (y1 == y2) {
      t[y1][x1] = '>';
      t[y2][x2] = '<';
    } else {
      t[y1][x1] = 'v';
      t[y2][x2] = '^';
    }
  }
  REP(i, n) cout << t[i] << '\n';
  return 0;
}


Measured memory_bytes: 4112