#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <utility>
#include <algorithm>
#include <functional>

using namespace std;

#define rep(i,n) for((i)=0;(i)<(int)(n);(i)++)
#define foreach(itr,c) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
template<class T> void pp(T a, T b){ for(T i = a; i != b; ++i) cout << *i << ' '; cout << endl; }

#define INF "|"

struct Edge {
  int from, to;
  string cost;
  Edge(int from_, int to_, string cost_){
    from = from_;
    to = to_;
    cost = cost_;
  }
  Edge(){
    from = to = 0;
    cost = "";
  }
};

int n,a,s,g;
Edge edge[410];
string d[50];

int main(){
  int i;

  while(1){
    scanf("%d %d %d %d",&n,&a,&s,&g);
    if(n == 0 && a == 0 && s == 0 && g == 0) break;

    rep(i,a){
      int from,to;
      string cost;
      // cin >> from >> to >> cost;
      cin >> to >> from >> cost;
      Edge e(from,to,cost);
      edge[i] = e;
    }

    rep(i,n) d[i] = INF;
    d[g] = "";
    int count = 0,cc=0;
    while(1){
      bool update = false;
      rep(i,a){
        Edge e = edge[i];
        if(d[e.from] != INF && d[e.to] > e.cost + d[e.from]){ // d[0] > d[0] + "a"
          // cout << d[e.to]<< ' ' <<  d[e.from] << ' ' <<  e.cost << endl;
          d[e.to] = e.cost + d[e.from];
          update = true;
          if(e.to == s && count >= n+1) cc++;
        }
      }
      count++;
      if(cc >= 1) break;
      if(count >= 500) break;
      if(!update) break;
    }

    cout << ((d[s] == "|" || cc >= 1) ? "NO" : d[s]) << endl;
  }

  return 0;
}