#!/usr/bin/python

import sys
G = [line[:-1] for line in sys.stdin]
Y = len(G)
X = max(len(g) for g in G)
G = [(g + ' '*X)[:X] for g in G]

# step 1 - run a befunge interpreter to get an execution trace
output = ''
stack = []
trace = []

def push(x):
  global stack
  stack.append(x)

def pop():
  global stack
  if stack:
    x = stack[-1]
    stack = stack[:-1]
    return x
  else:
    return 0

def read(p):
  if p[1] < 0 or p[1] >= len(G): return ' '
  if p[0] < 0 or p[0] >= len(G[p[1]]): return ' '
  return G[p[1]][p[0]]

def add(p,d):
  p = (p[0]+d[0], p[1]+d[1])
  if p[0] < 0: p = (p[0]+X, p[1])
  if p[0] >= X: p = (p[0]-X, p[1])
  if p[1] < 0: p = (p[0], p[1]+Y)
  if p[1] >= Y: p = (p[0], p[1]-Y)
  return p

p = (0,0)
d = (1,0)

# basic blocks are a triple of pairs: start position, start direction, end position
bb = []
startpos = p
startdir = d

while 1:
  trace += [(p,d)]
  c = read(p)
  if c == ' ': pass
  if c >= '0' and c <= '9': push(ord(c) - ord('0'))
  if c == '+': x = pop(); y = pop(); push(y + x)
  if c == '-': x = pop(); y = pop(); push(y - x)
  if c == '*': x = pop(); y = pop(); push(y * x)
  if c == '/': x = pop(); y = pop(); push(y / x)
  if c == '%': x = pop(); y = pop(); push(y % x)
  if c == '!': push(0 if pop() else 1)
  if c == '`': x = pop(); y = pop(); push(1 if y>x else 0)
  if c == '>': d = (1,0)
  if c == '<': d = (-1,0)
  if c == '^': d = (0,-1)
  if c == 'v': d = (0,1)
  if c == '_':
    d = (-1,0) if pop() else (1,0)
    if (startpos, startdir, p) not in bb: bb.append((startpos, startdir, p))
    startpos = add(p, d)
    startdir = d
  if c == '|':
    d = (0,-1) if pop() else (0,1)
    if (startpos, startdir, p) not in bb: bb.append((startpos, startdir, p))
    startpos = add(p, d)
    startdir = d
  if c == '"':
    p = add(p,d)
    while read(p) != '"': push(ord(read(p))); p = add(p, d)
  if c == ':': x = pop(); push(x); push(x)
  if c == '\\': x = pop(); y = pop(); push(x); push(y)
  if c == '$': pop()
  if c == '.': output += '%d' % pop()
  if c == ',': output += '%c' % pop()
  if c == '#': p = add(p,d)
  if c == '@':
    bb.append((startpos, startdir, p))
    break
  
  p = add(p,d)

# map to look up basic block starts
bblookup = {}
for i,(p,d,q) in enumerate(bb):
  bblookup[p,d] = i

# control flow graph.  List of pairs (basic block body, list of branch destinations)
graph = []

for p, d, q in bb:
  # find first instance of this basic block in the trace
  k = trace.index((p, d))

  # generate basic block body
  line = ''
  while 1:
    p, d = trace[k]
    if p == q: break
    c = read(p)
    if c in ' ><^v_|#': pass
    if c in '0123456789+-*/%!`:\\$.,': line += c
    if c == '"':
      line += '"'
      p = add(p, d)
      while read(p) != '"': line += read(p); p = add(p, d)
      line += '"'
    k += 1

  # end of basic block
  c = read(q)
  if c == '@':
    line += '@'
    dest = ()
  if c == '|':
    a = bblookup.get(((q[0],q[1]-1), (0,-1)), None)
    b = bblookup.get(((q[0],q[1]+1), (0,1)), None)
    if a is None:
      dest = (b,)
    elif b is None:
      dest = (a,)
    else:
      dest = (a,b)
  if c == '_':
    a = bblookup.get(((q[0]-1,q[1]), (-1,0)), None)
    b = bblookup.get(((q[0]+1,q[1]), (1,0)), None)
    if a is None:
      dest = (b,)
    elif b is None:
      dest = (a,)
    else:
      dest = (a,b)

  graph.append((line, dest))

# for each block, the column that routes to it on each side of the routing area
left = [-1] * len(graph)
right = [-1] * len(graph)

used = set()
for i, (block, dest) in enumerate(graph):
  # find locations that need to reach the block
  A = []
  for j, (block, dest) in enumerate(graph):
    if len(dest) > 0 and dest[0] == i:
      A += [j]
  if not A: continue  # never a target
  A += [i]
  A = range(min(A), max(A)+1)
  
  # find a column without conflicts
  for c in xrange(len(graph)):
    if not any((c,j) in used for j in A):
      for j in A: used.add((c,j))
      break
  left[i] = c

used = set()
for i, (block, dest) in enumerate(graph):
  # find locations that need to reach the block
  A = []
  for j, (block, dest) in enumerate(graph):
    if len(dest) == 2 and dest[1] == i:
      A += [j]
  if not A: continue  # never a target
  A += [i]
  A = range(min(A), max(A)+1)
  
  # find a column without conflicts
  for c in xrange(len(graph)):
    if not any((c,j) in used for j in A):
      for j in A: used.add((c,j))
      break
  right[i] = c

leftsize = max(left) + 1
rightsize = max(right) + 1

inroute = [{} for i in xrange(len(graph))]
midroute = [{} for i in xrange(len(graph))]
outroute = [{} for i in xrange(len(graph))]

# compute outline of routing area
for i, (block, dest) in enumerate(graph):
  if len(dest) >= 1:
    d = dest[0]
    L = left[d]
    if d > i: # downward
      for j in xrange(i+1, d): inroute[j][L] = midroute[j][L] = outroute[j][L] = ' '
    else: # upward
      for j in xrange(d, i+1): inroute[j][L] = midroute[j][L] = outroute[j][L] = ' '
  if len(dest) == 2:
    d = dest[1]
    R = leftsize + 1 + 2 * right[d]
    if d > i: # downward
      for j in xrange(i+1, d): inroute[j][R] = midroute[j][R] = outroute[j][R] = ' '
    else: # upward
      for j in xrange(d, i+1): inroute[j][R] = midroute[j][R] = outroute[j][R] = ' '

# add routing code
for i, (block, dest) in enumerate(graph):
  if len(dest) >= 1:
    d = dest[0]
    L = left[d]
    inroute[d][L] = '>'
    outroute[i][L] = 'v' if d > i else '^'
  if len(dest) == 2:
    outroute[i][leftsize] = '_'
    d = dest[1]
    R = leftsize + 1 + 2 * right[d]
    inroute[d][R] = '>'
    outroute[i][R] = 'v' if d > i else '^'
    outroute[i][R+1] = '#'

# fill in holes
for i in xrange(len(graph)):
  n = max(inroute[i].keys()) if inroute[i] else 0
  for j in xrange(n):
    if j not in inroute[i]: inroute[i][j] = ' '
  n = max(midroute[i].keys()) if midroute[i] else 0
  for j in xrange(n):
    if j not in midroute[i]: midroute[i][j] = ' '
  n = max(outroute[i].keys()) if outroute[i] else 0
  for j in xrange(n):
    if j not in outroute[i]: outroute[i][j] = ' '

# make routing area into strings
for i in xrange(len(graph)):
  inroute[i] = ''.join(map(lambda x:x[1], sorted(inroute[i].items())))
  midroute[i] = ''.join(map(lambda x:x[1], sorted(midroute[i].items())))
  outroute[i] = ''.join(map(lambda x:x[1], sorted(outroute[i].items())))

# pack the given befunge line into an area with the given line sizes.
# packing is done in zig-zag row major order.
def pack(line, sizes):
  if not sizes:
    if line: return None
    return []
  s = sizes[0]
  if len(line) <= s and len(sizes) == 1: return [line.ljust(s)]
  if s < 2: return None
  if len(line) < s:
    r = pack('>', sizes[1:])
    if r: return [line.ljust(s-1) + 'v'] + r
    return None
  if line[:s-1].count('"')%2 == 1: # breaking a quoted string
    if s < 4: return None
    if line[s-2] == '"':
      return pack(line[:s-2] + ' ' + line[s-2:], sizes)
    else:
      return pack(line[:s-2] + '""' + line[s-2:], sizes)
  rest = pack('>' + line[s-1:], sizes[1:])
  if rest is None: return None
  return [line[:s-1] + 'v'] + rest

# max width of routing area
R = leftsize + 1 + 2 * rightsize

# pack the i'th basic block given the width w of the main code area.
def packwidth(i, w):
  line = graph[i][0]
  if line[-1] == '@':
    n = 1
    while n <= len(line):
      sizes = [R + w - len(inroute[i])] + (n - 1) * [R + w - len(midroute[i])]
      r = pack(line, sizes)
      if r: return r
      n += 1
  else:
    n = 2
    while n <= len(line):
      sizes = [R + w - len(inroute[i])] + (n - 2) * [R + w - len(midroute[i])] + [R + w - len(outroute[i])]
      r = pack(line, sizes)
      if r: return r
      n += 2
  return None

# find best width
W = 0
bestarea = 1e30
for w in xrange(max(len(line) for line, dest in graph)):
  h = 0
  for i in xrange(len(graph)):
    r = packwidth(i, w)
    if not r: h = -1; break
    h += len(r)
  if h < 0: continue
  area = (R + w) * h
  if area < bestarea: W = w; bestarea = area

def makeint(n):
  if n <= 9: return '%d' % n
  for i in xrange(9, 1, -1):
    if n % i == 0: return '%s%d*' % (makeint(n / i), i)
  s = []
  for i in xrange(9, 0, -1):
    s += ['%s%d+' % (makeint(n - i), i)]
  return sorted((len(x), x) for x in s)[0][1]

# how about just straight output?
inquote = 0
linear = ''
for c in output[::-1]:
  if c >= ' ' and c <= '~' and c != '"':
    if not inquote: linear += '"'; inquote = 1
    linear += c
  else:  #TODO: doesn't do embedded nulls correctly.
    if inquote: linear += '"'; inquote = 0
    linear += makeint(ord(c))
if inquote: linear += '"'
linear += '>:#,_@'
if bestarea > len(linear):
  print linear
  sys.exit(0)

# print grid result
for i in xrange(len(graph)):
  h = len(packwidth(i, W))
  for w in xrange(W+1):
    r = packwidth(i, w)
    if not r: continue
    if len(r) == h: break
  print inroute[i] + r[0]
  for j in xrange(1, len(r)-1):
    if j % 2 == 0:
      print midroute[i] + r[j]
    else:
      print midroute[i] + r[j][::-1].replace('>', '<')
  if len(r) > 1:
    print outroute[i] + r[-1][::-1].replace('>', '<')
