
class Node
  attr_reader :go, :come

  def initialize(id)
    @id = id
    @go = []
    @come = []
  end
end

class Arrow
  attr_reader :source, :sink, :label
  
  def initialize(source, sink, label)
    @source = source
    @sink = sink
    @label = label
    source.go << self
    source.come << self
  end
end

class Result
  attr_reader :target, :spell

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

def advance(table, nodes, arrows)
  next_table = table
  nodes.each do |node|
    best = table[node]
    node.go.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)
  return false unless result

  used = {}
  loop do
    node = result.target
    return true unless node
    return false if used[node]
    used[node] = true
    result = table[node]
  end
end

def work(nodes, arrows, start, goal)
  table = {goal => Result.new(nil, '')}
  (nodes.size*6).times do
    table = advance(table, nodes, arrows)
  end
  result = table[start]
  puts check(table, result) ? result.spell : 'NO'
end

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

  nodes = (0...n).map{|i| Node.new(i)}

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

  start = nodes[s]
  goal = nodes[g]

  work(nodes, arrows, start, goal)
end