static void Main() { var(n, m) = Read2(); var s = Array.ConvertAll(new bool[n], _ => Console.ReadLine().ToCharArray()); var vs0 = new List <int>(); var vs1 = new List <int>(); var vs1Inv = Array.ConvertAll(new bool[n * m], _ => - 1); // checker board for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (s[i][j] == '#') { continue; } var v = m * i + j; if ((i + j) % 2 == 0) { vs0.Add(v); } else { vs1Inv[v] = vs1.Count; vs1.Add(v); } } } var bm = new BipartiteMatching(vs0.Count, vs1.Count); for (int i = 0; i < vs0.Count; i++) { var v = vs0[i]; if (v - m >= 0 && vs1Inv[v - m] != -1) { bm.AddEdge(i, vs1Inv[v - m]); } if (v + m < n * m && vs1Inv[v + m] != -1) { bm.AddEdge(i, vs1Inv[v + m]); } if (v % m != 0 && vs1Inv[v - 1] != -1) { bm.AddEdge(i, vs1Inv[v - 1]); } if (v % m != m - 1 && vs1Inv[v + 1] != -1) { bm.AddEdge(i, vs1Inv[v + 1]); } } var res = bm.Dinic(); foreach (var e in res) { var v0 = vs0[e[0]]; var v1 = vs1[e[1]]; var(i0, j0) = (v0 / m, v0 % m); var(i1, j1) = (v1 / m, v1 % m); if (i0 == i1) { s[i0][Math.Min(j0, j1)] = '>'; s[i0][Math.Max(j0, j1)] = '<'; } else { s[Math.Min(i0, i1)][j0] = 'v'; s[Math.Max(i0, i1)][j0] = '^'; } } Console.WriteLine(res.Length); foreach (var r in s) { Console.WriteLine(new string(r)); } }