require 'set'

class Heap
  def initialize
    @obj_array = []
    @key_array = []
    @index = {}
  end

  def add(obj, key)
    if @index[obj]
      update_key(obj, key)
    else
      @obj_array << obj
      @key_array << key
      @index[obj] = @obj_array.size - 1
      lift_up(@obj_array.size - 1)
    end
  end

  def swap(i, j)
    u = @obj_array[i]
    v = @obj_array[j]
    @index[u], @index[v] = j, i
    @obj_array[i], @obj_array[j] = v, u
    @key_array[i], @key_array[j] = @key_array[j], @key_array[i]
  end

  def lift_up(i)
    return if i == 0
    j = (i - 1) / 2
    if @key_array[i] < @key_array[j]
      swap(i, j)
      lift_up(j)
    end
  end

  def del_min
    raise "heap is empty!" if empty?
    min = [@obj_array[0], @key_array[0]]
    if @obj_array.size > 1
      swap(0, @obj_array.size-1)
      @obj_array.pop
      @key_array.pop
      lift_down(0)
    else
      @obj_array.pop
      @key_array.pop
    end
    @index.delete(min[0])
    min
  end

  def update_key(obj, new_key)
    i = @index[obj]
    old_key = @key_array[i]
    return if new_key > old_key
    @key_array[i] = new_key
    lift_up(i)
  end

  def lift_down(i)
    j = 2 * i + 1
    k = j + 1
    if k >= @obj_array.size
      return if j >= @obj_array.size
      if @key_array[i] > @key_array[j]
        swap(i, j)
        lift_down(j)
      end
    else
      l = (@key_array[j] < @key_array[k] ? j : k)
      if @key_array[i] > @key_array[l]
        swap(i, l)
        lift_down(l)
      end
    end
  end

  def empty?
    @obj_array.empty?
  end
end

def dijkstra(g, t, s1, s2)
  queue = Heap.new
  queue.add(t * 1000, 0)
  count = 0
  dist = {}
  until queue.empty?
    x, d = queue.del_min
    dist[x] = d
    g[x].each do |y, w|
      next if dist[y]
      queue.add(y, d + w)
    end
  end
  dist
end

loop do
# .times do
  n, m, s1, s2, t = gets.split.map(&:to_i)
  break if n == 0

  magical = []
  orig_graph = Hash[(1..n).map {|i| [i, {}] }]

  m.times do
    i, j, w = gets.chomp.split
    i, j = i.to_i, j.to_i
    if w == ?x
      magical << [i, j]
      magical << [j, i]
    else
      orig_graph[i][j] = w.to_i
      orig_graph[j][i] = w.to_i
    end
  end

  g = {}
  (0..magical.size).each do |l|
    (1..n).each do |i|
      x = i * 1000 + l
      g[x] = {}
      orig_graph[i].each do |j, w|
        y = j * 1000 + l
        g[x][y] = w
      end
    end
  end
  (1..magical.size).each do |l|
    magical.each do |i, j|
      x = i * 1000 + l - 1
      y = j * 1000 + l
      g[x][y] = 0
    end
  end

  xs = Set[0]

  dist = dijkstra(g, t, s1, s2)

  valid1 = [] 
  min = nil
  (0..magical.size).each do |i|
    t = s1 * 1000 + i
    next if !dist[t]
    if min
      if dist[t] < min
        valid1 << [i, dist[t]]
        min = dist[t]
      end
    else
      valid1 << [i, dist[t]]
      min = dist[t]
    end
  end
  valid1.combination(2) do |l1, l2|
    i1, d1 = l1
    i2, d2 = l2
    x = (d1 - d2).to_f / (i2 - i1)
    xs << x.ceil if x.ceil > 0
    xs << x.floor if x.floor > 0
  end

  valid2 = [] 
  min = nil
  (0..magical.size).each do |i|
    t = s2 * 1000 + i
    next if !dist[t]
    if min
      if dist[t] < min
        valid2 << [i, dist[t]]
        min = dist[t]
      end
    else
      valid2 << [i, dist[t]]
      min = dist[t]
    end
  end
  valid2.combination(2) do |l1, l2|
    i1, d1 = l1
    i2, d2 = l2
    x = (d1 - d2).to_f / (i2 - i1)
    xs << x.ceil if x.ceil > 0
    xs << x.floor if x.floor > 0
  end

  valid1.each do |i1, d1|
    valid2.each do |i2, d2|
      next if i1 == i2
      x = (d1 - d2).to_f / (i2 - i1)
      xs << x.ceil if x.ceil > 0
      xs << x.floor if x.floor > 0
    end
  end

  best = Float::INFINITY
  xs.each do |x|
    min1 = valid1.map {|i, d| x * i + d }.min
    min2 = valid2.map {|i, d| x * i + d }.min
    d = (min1 - min2).abs
    best = d if d < best
  end
  p best
end



Measured memory_bytes: 132808