open Format

let n = int_of_string Sys.argv.(1)
let lines = ref []

let () =
  try
    while true do
      let s = read_line () in
      if s = "" then raise End_of_file;
      if String.length s = n then
	let l = Array.init n (fun i -> s.[i] <> '|') in
	lines := l :: !lines
    done
  with End_of_file ->
    ()

let lines = List.rev !lines

let compatible l1 l2 =
  try
    for i = 0 to n-1 do if l1.(i) && l2.(i) then raise Exit done; true
  with Exit ->
    false

let merge l1 l2 = Array.init n (fun i -> l1.(i) || l2.(i))

let rec compact = function
  | [] | [_] as l -> 
     l
  | l1 :: l2 :: lines -> 
     if compatible l1 l2 then 
       compact (merge l1 l2 :: lines) 
     else 
       l1 :: compact (l2 :: lines)

let included l1 l2 =
  let sup1 = ref true in
  let sup2 = ref true in
  try
    for i = 0 to n-1 do 
      if l1.(i) then sup1 := not !sup1;
      if l2.(i) then sup2 := not !sup2;
      if l1.(i) && not l2.(i) then raise Exit;
      if l1.(i) && l2.(i) && !sup1 <> !sup2 then raise Exit
    done; 
    true
  with Exit ->
    false

let swapable l1 l2 = included l1 l2 || included l2 l1

let rec swap = function
  | [] | [_] as l -> 
     l
  | [l1; l2] as l -> 
     if swapable l1 l2 then [l2; l1] else l
  | l1 :: l2 :: l3 :: lines -> 
     if swapable l1 l2 then 
       l2 :: (if compatible l1 l3 
	      then l1 :: l3 :: swap lines
	      else swap (l1 :: l3 :: lines))
     else 
       l1 :: swap (l2 :: l3 :: lines)

let display_one_line l =
  let sup = ref true in
  Array.iteri 
    (fun i b -> 
       if b then begin
	 if !sup then printf ">" else printf "<";
	 sup := not !sup
       end else
	 printf "|")
    l;
  printf "@."

let display = List.iter display_one_line

let () =
  let rec loop lines =
    let size = List.length lines in
    eprintf "%d lines@." size;
    let lines = compact lines in
    let lines = swap lines in
    if List.length lines < size then loop lines else display lines
  in
  loop lines