
class Arrow
  attr_reader :source, :sink, :label
  
  def initialize(source, sink, label)
    @source = source
    @sink = sink
    @label = label
  end
end

class Result
  attr_reader :target, :spell

  def initialize(target, spell)
    @target = target
    @spell = spell
  end
end

def advance(table, n, goes, arrows)
  next_table = [nil] * n
  (0...n).each do |node|
    best = table[node]
    goes[node].each do |arrow|
      result = table[arrow.sink]
      next unless result
      test = arrow.label + result.spell
      if !best || test < best.spell
        best = Result.new(arrow.sink, test)
      end
    end
    next_table[node] = best if best
  end
  next_table
end

def check(table, result, n)
  used = [false] * n
  loop do
    node = result.target
    return true unless node
    return false if used[node]
    used[node] = true
    result = table[node]
  end
end

def work(n, arrows, start, goal)
  goes = (0...n).map{[]}
  arrows.each do |arrow|
    goes[arrow.source] << arrow
  end
  table = {goal => Result.new(nil, '')}
  n.times do
    table = advance(table, n, goes, arrows)
  end
  return false unless table[start]
  (n*5).times do
    table = advance(table, n, goes, arrows)
  end
  result = table[start]
  puts check(table, result, n) ? result.spell : 'NO'
end

loop do
  n, a, s, g = STDIN.gets.split.map(&:to_i)
  break if n == 0

  arrows = (0...a).map do |i|
    x, y, lab = STDIN.gets.split
    x = x.to_i
    y = y.to_i
    Arrow.new(x, y, lab)
  end

  start = s
  goal = g

  work(n, arrows, start, goal)
end