Problem:
Strange Key

Professor Tsukuba invented a mysterious jewelry box that can be opened
with a special gold key whose shape is very strange. It is composed
of gold bars joined at their ends. Each gold bar
has the same length and is placed parallel to one of the three
orthogonal axes in a three dimensional space,
i.e., x-axis, y-axis and z-axis.

The locking mechanism of the jewelry box
is truly mysterious, but the shape of the key is known.
To identify the key of the jewelry box, he gave a way to describe
its shape.

The description
indicates a list of connected paths that completely defines the shape
of the key: the gold bars of the key are arranged along the paths and
joined at their ends.
Except for the first path,
each path must start from an end point of a gold bar on a previously
defined path.
Each path is represented by a sequence of elements, each of which is one
of six symbols (+x, -x, +y, -y, +z and -z) or a positive integer.
Each symbol indicates the direction from an end point to the other end
point of a gold bar along the path. Since each gold bar is
parallel to one of the three orthogonal axes, the 6 symbols are enough to
indicate the direction. Note that a description of a path has
direction but the gold bars themselves have no direction.

An end point of a gold bar can have a label, which is a positive integer.
The labeled point may be referred to as the beginnings of other paths.
In a key description, the first occurrence of a positive integer
defines a label of a point and each subsequent occurrence of the same
positive integer indicates the beginning of a new path at the point.

An example of a key composed of 13 gold bars is depicted
in Figure 1.

The following sequence of lines

19
1 +x 1 +y +z 3 +z
3 +y -z +x +y -z -x +z 2 +z
2 +y

is a description of the key in Figure 1.
Note that newlines have the same role as space characters in the
description, so that "19 1 +x 1 +y +z 3 +z 3 +y -z +x +y -z -x +z
2 +z 2 +y" has the same meaning.

The meaning of this description is quite simple.
The first integer "19" means the number of
the following elements in this description.
Each element is one of the 6 symbols or a positive integer.

The integer "1" at the head of the second line
is a label attached to the starting point of the first path.
Without loss of generality,
it can be assumed that the starting point of the first path is the
origin, i.e., (0,0,0), and that the length of each gold bar is 1.
The next element "+x" indicates that the first gold bar
is parallel to the x-axis,
so that the other end point of the gold bar is at (1,0,0).
These two elements "1" and "+x" indicates
the first path consisting of only one gold bar.
The third element of the second line in the description is the positive
integer "1", meaning that the point with the label "1", i.e., the
origin (0,0,0) is the beginning of a new path.
The following elements "+y", "+z", "3", and "+z" indicate the second
path consisting of three gold bars. Note that this "3" is its first
occurrence so that the point with coordinates (0,1,1) is labeled "3".
The head of the third line "3" indicates
the beginning of the third path and so on.
Consequently, there are four paths by which the shape of the key in
Figure 1 is completely defined.

Note that there are various descriptions of the same key since there
are various sets of paths that cover the shape of the key.
For example,
the following sequence of lines

19
1 +x 1 +y +z 3 +y -z +x +y -z -x +z 2 +y
3 +z
2 +z

is another description of the key in Figure 1, since
the gold bars are placed in the same way.

Furthermore, the key may be turned 90-degrees around
x-axis, y-axis or z-axis several times and may be moved parallelly.
Since any combinations of rotations and parallel moves don't change
the shape of the key, a description of a rotated and moved key also
represent the same shape of the original key. For example, a
sequence

17
+y 1 +y -z +x
1 +z +y +x +z +y -x -y 2 -y
2 +z

is a description of a key in Figure 2 that represents the same key
as in Figure 1.
Indeed, they are congruent under a rotation around x-axis and
a parallel move.

Your job is to write a program to
judge whether or not the given two descriptions define the same key.

Note that paths may make a cycle.
For example, "4 +x +y -x -y" and "6 1 +x 1 +y +x -y"
are valid descriptions. However, two or more gold bars must not be placed at the same position.
For example, key descriptions
"2 +x -x"
and
"7 1 +x 1 +y +x -y -x" are invalid.

Input

An input data is a list of pairs of key descriptions followed by
a zero that indicates the end of the input.
For p pairs of key descriptions, the input is given in the
following format.

key-description1-a

key-description1-b

key-description2-a

key-description2-b

...

key-descriptionp-a

key-descriptionp-b

0

Each key description (key-description) has the following format.

n
e1 e2
...
ek
...
en

The positive integer n indicates the number of the following elements
e1, ...,
en .
They are separated by one or more space characters and/or newlines.
Each element ek is
one of the six symbols
(+x, -x, +y, -y, +z and -z)
or a positive integer.

You can assume that each label is a positive integer that is less than 51,
the number of elements in a single key description is less than 301,
and the number of characters in a line is less than 80.
You can also assume that the given key descriptions are valid and
contain at least one gold bar.

Output

The number of output lines should be equal to that of
pairs of key descriptions given in the input.
In each line, you should output one of two words "SAME",
when the two key descriptions represent the same key, and
"DIFFERENT", when they are different.
Note that the letters should be in upper case.

Sample Input

19
1 +x 1 +y +z 3 +z
3 +y -z +x +y -z -x +z 2 +z
2 +y
19
1 +x 1 +y +z 3 +y -z +x +y -z -x +z 2 +y
3 +z
2 +z
19
1 +x 1 +y +z 3 +z
3 +y -z +x +y -z -x +z 2 +y
2 +z
18
1 -y
1 +y -z +x
1 +z +y +x +z +y -x -y 2 -y
2 +z
3 +x +y +z
3 +y +z -x
0

Output for the Sample Input

SAME
SAME
DIFFERENT

Solution in Ruby (judge verdict: Wrong Answer)

### constant

DXYZS = {
  '+x' => [1, 0, 0], '-x' => [-1, 0, 0],
  '+y' => [0, 1, 0], '-y' => [0, -1, 0],
  '+z' => [0, 0, 1], '-z' => [0, 0, -1],
}

M_ID = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
M_RX = [[1, 0, 0], [0, 0, -1], [0, 1, 0]]
M_RY = [[0, 0, 1], [0, 1, 0], [-1, 0, 0]]
M_RZ = [[0, -1, 0], [1, 0, 0], [0, 0, 1]]

### subroutines

def read_keyops(line)
  ops = line.split
  n = ops.shift.to_i

  while ops.length < n
    ops += gets.strip.split
  end

  ops
end

def gen_key(ops)
  cpt = [0, 0, 0]
  pids = {}
  refs = {}

  pids[cpt] = 0
  npt = 1

  pts = [cpt]
  edges = []

  for op in ops
    case op
    when '+x', '-x', '+y', '-y', '+z', '-z'
      dxyz = DXYZS[op]
      pt1 = [cpt[0] + dxyz[0], cpt[1] + dxyz[1], cpt[2] + dxyz[2]]

      if pids[pt1].nil?
        pids[pt1] = npt
        npt += 1
        pts << pt1
      end

      id0 = pids[cpt]
      id1 = pids[pt1]
      edges << [id0, id1]

      cpt = pt1
    else
      if refs[op].nil?
        refs[op] = cpt
      else
        cpt = refs[op]
      end
    end
  end

  [pts, edges]
end

def mul_mat(m0, m1)
  mr = [[0] * 3] * 3
  for i in (0..2)
    for j in (0..2)
      for k in (0..2)
        mr[i][j] += m0[i][k] * m1[k][j]
      end
    end
  end
  mr
end

def mul_mat_p(m, p)
  pr = [0] * 3
  for i in (0..2)
    for j in (0..2)
      pr[i] += m[i][j] * p[j]
    end
  end
  pr
end

def key_rot(key, xi, yi, zi)
  pts0 = []

  for pt in key[0]
    pt0 = pt.clone
    xi.times.each{pt0 = mul_mat_p(M_RX, pt0)}
    yi.times.each{pt0 = mul_mat_p(M_RY, pt0)}
    zi.times.each{pt0 = mul_mat_p(M_RZ, pt0)}
    pts0 << pt0
  end

  [pts0, key[1]]
end

def key_mv(key, dx, dy, dz)
  pts0 = []

  for pt in key[0]
    pts0 << [pt[0] + dx, pt[1] + dy, pt[2] + dz]
  end

  [pts0, key[1]]
end

def key_equal?(key0, key1)
  pts0, edges0 = key0
  pts1, edges1 = key1
  return false if pts0.length != pts1.length || edges0.length != edges1.length

  rots = [0, 0, 0]

  loop do
    key1r = key_rot(key1, *rots)
    pts1r, edges1r = key1r

    for pt1r in pts1r
      key1rm = key_mv(key1r, -pt1r[0], -pt1r[1], -pt1r[2])
      pts1rm, edges1rm = key1rm

      pmap = []
      for pt1rm in pts1rm
        i = pts0.index(pt1rm)
        break if i.nil?
        pmap << i
      end

      next if pmap.length < pts0.length

      emap = []
      for e1rm in edges1rm
        ep0, ep1 = e1rm
        pep0 = pmap[ep0]
        pep1 = pmap[ep1]

        i0 = edges0.index([pep0, pep1])
        if ! i0.nil?
          emap << i0
          next
        end
        i1 = edges0.index([pep1, pep0])
        if ! i1.nil?
          emap << i1
          next
        end
        break
      end

      next if emap.length < edges0.length

      return true
    end

    k = 0
    loop do
      return false if k >= 3
      rots[k] += 1
      break if rots[k] <= 3
      rots[k] = 0
      k += 1
    end
  end

  false
end


### main

loop do
  line = gets.strip
  break if line == '0'

  keyops0 = read_keyops(line)
  keyops1 = read_keyops(gets.strip)
  #p keyops0
  #p keyops1

  key0 = gen_key(keyops0)
  key1 = gen_key(keyops1)
  #p key0
  #p key1

  puts (key_equal?(key0, key1) ? 'SAME' : 'DIFFERENT')
end