#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
#include<utility>
using namespace std;

#define rep(i,n) for(int i=0;i<n;i++)
#define fr(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define mp make_pair
typedef pair<int,int> pi;

const int inf=1<<28;
int dy[]={0,1,0,-1},dx[]={-1,0,1,0};

int n,a,s,g;
vector<vector<pair<int,string> > > e;
string dp[40][500];

struct Node{
	string str; int cur;
	Node(int a,string b):cur(a),str(b){}
	Node(){}
	bool operator<(const Node &r)const{
		return str>r.str;
	}
};

int main(){
	while(cin>>n>>a>>s>>g,n)
	{
		e.clear(); e.resize(n);
		rep(i,a)
		{
			string str;
			int x,y; cin>>x>>y>>str;
			e[x].push_back(mp(y,str));
		}
		
		rep(i,n)rep(j,500)dp[i][j]="";
		priority_queue<Node> Q; Q.push(Node(s,""));
		while(!Q.empty())
		{
			int cur=Q.top().cur; string cstr=Q.top().str; Q.pop();
			if(cstr.size()>=500)continue;
			if(cur==g)
			{
				if(cstr.size()>=400)goto FAIL;
				cout<<cstr<<endl; goto END;
			}
			
			fr(i,e[cur])
			{
				int nxt=i->first; string nstr=cstr+i->second;
				if(nstr.size()>=500)continue;
				if(dp[nxt][nstr.size()]!=""&&dp[nxt][nstr.size()]<=nstr)continue;
				dp[nxt][nstr.size()]=nstr; Q.push(Node(nxt,nstr));
			}
		}
		FAIL:cout<<"NO"<<endl; END:;
	}
	return 0;
}