#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<algorithm>
#include<vector>
using namespace std;
#define fr first
#define sc second
typedef pair<string,int> P;
struct edge{
  int to;
  string cost;
  edge(){}
  edge(int to,string cost):to(to),cost(cost){};
};
vector< vector<edge> > info;
int n,a,s,g;
string d[40][400];
string Dijkstra(){
  priority_queue< P,vector<P>,greater<P> > que;
  for(int i=0;i<n;i++) for(int j=0;j<400;j++) d[i][j] = "";
  que.push(P("",s));
  d[s][0] = "";
  while(!que.empty()){
    P p = que.top();
    int now = p.sc;
    string nowstr = p.fr;
    que.pop();
    if( now == g ) return (nowstr.size() >= 300 ? "NO" : p.fr);
    if( d[now][nowstr.size()] != "" && d[now][nowstr.size()] < nowstr ) continue;
    for(int i = 0 ; i < info[now].size() ; i++ ){
      edge e = info[now][i];
      string next_str = nowstr + e.cost;
      if( next_str.size() >= 400 ) continue;
      if( d[e.to][next_str.size()] == "" || next_str < d[e.to][next_str.size()] ){
        d[e.to][next_str.size()] = next_str;
        que.push(P(next_str , e.to ));
      }
    }
  }
  return "NO";
}
int main(){
  while(cin >> n >> a >> s >> g , n){
    info.resize(n);
    for(int i = 0 , x , y ; i < a ; i++ ){
      string s;
      cin >> x >> y >> s;
      info[x].push_back(edge(y,s));
    }
    cout << Dijkstra() << endl;
    info.clear();
  }
}