#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/trie_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#pragma GCC target("avx2")
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")

#define int long long
#define ll long long
#define all(v) v.begin(), v.end()
#define intvect vector<int>
#define pii pair<int, int>
#define mii map<int, int>
#define fo(i, n) for (int i = 0; i < n; ++i)
#define Fo(i, k, n) for (int i = k; i < n; ++i)
#define ld long double
#define deb(x) cout << #x << " " << x << endl;
#define pb push_back
#define pob pop_back
#define lcm(a, b) (a / __gcd(a, b) * b)
#define F first
#define S second
#define ull unsigned long long

typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update>
    indexed_set;

const ll mod = 10000007;
const ll N = (ll)5e5 + 4;

template <typename... T>
void read(T &... args)
{
    ((cin >> args), ...);
}

template <typename... T>
void write(T &&... args)
{
    ((cout << args), ...);
}

void vjudge()
{
#ifndef RTE
    if (fopen("input.txt", "r"))
    {
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    }
#endif
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}

bool comp(pair<int, int> x, pair<int, int> y)
{
    if (x.first != y.first)
        return x.first < y.first;
    return x.second < y.second;
}
void solve()
{
    int n, w;
    cin >> n >> w;

    vector<pair<int, int>> e;
    for (int i = 0; i < n; ++i)
    {
        int a, b, p;
        cin >> a >> b >> p;
        e.emplace_back(a, -p);
        e.emplace_back(b - 1, p);
    }
    sort(e.begin(), e.end());
    pair<int, int> ans = {0, -1};
    int cur = 0;
    for (pair<int, int> p : e)
    {
        cur += -p.second;
        if (cur > ans.first)
        {
            ans = {cur, p.first};
        }
    }
    if (ans.first > w)
        cout << "No";
    else
        cout << "Yes";
}
int32_t main()
{
    clock_t start, end;
    start = clock();
    vjudge();
    int t = 1;
    // cin >> t;
    while (t--)
        solve();
    end = clock();
    double waste = double(end - start) / double(CLOCKS_PER_SEC);
    cerr << "Time wasted by program is : " << fixed
         << waste << setprecision(15);
    cerr << " sec " << endl;
}

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>
using namespace __gnu_pbds;
using namespace std;


#define LETS_GET_SCHWIFTY ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);  
#define ff              first
#define ss              second
#define int             long long
#define ll              long long
#define pb              push_back
#define pii             pair<int,int>
#define vi              vector<int>
#define pqb             priority_queue<int>
#define pqs             priority_queue<int,vi,greater<int> >
#define setbits(x)      __builtin_popcountll(x)
#define zerobits(x)      __builtin_ctzll(x)
#define mod             998244353
#define inf             1e18
#define ps(x,y)         fixed<<setprecision(y)<<x
#define vpii            vector<pair<int,int> >
#define all(x)          x.begin(),x.end()
#define matrixprint(arr,a,b,c,d) for(int i=a;i<=c;i++){for(int j=b;j<=d;j++){cout<<arr[i][j]<<" ";}cout<<"\n";}
#define show(arr,x,y)   for(int i=x;i<=y;i++){cout<<arr[i]<<" ";}cout<<"\n"
#define sz(x)           (int)x.size()
#define db(x)           cout<<x<<"\n";

typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;

//insert,find_by_order,order_of_key,lower_bound,upper_bound;

#define TRACE
#ifdef TRACE
#define deb(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
    cout << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
    const char* comma = strchr(names + 1, ','); cout.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}
#else
#define deb(...)
#endif

  
//////////////////////////////code//////////////////////////////

const int N = 1e3 + 5;

vector<pair<int,char> >  adj[N];
int is[N][N];
int dp[N][N];


void solve()
{

		int n,m;
		cin >> n >> m;



		for(int i = 0;i < m; i++)
		{
				int u,v;
				char w;
				cin >> u >> v >> w;
				adj[u].pb({v,w});
				adj[v].pb({u,w});
				is[u][v] = is[v][u] = 1;
				//deb(v,u);
				//deb(sz(adj[u]),sz(adj[v]));
		}

		queue<pii>q;
	//	int dp[n + 1][n + 1];

		for(int i = 1;i <= n; i++)
			for(int j = 1;j <= m; j++)
				dp[i][j] = inf;

		dp[1][n] = 0;
		q.push({1,n});
		int ans = inf;

	//	deb(sz(adj[n]));

		while(!q.empty())
		{
				pii p = q.front();
				int node1 = p.ff, node2 = p.ss;
				q.pop();


				if(is[node1][node2])
				{ 
				 	 	ans = min(ans,dp[node1][node2] + 1);
				 	 	//deb(node1,node2,"1");
				  		continue;
				}
				//deb(node1,node2);

			    for(auto &c1 : adj[node1])
			    {      
			    	//deb("OK");
			    		for(auto &c2 : adj[node2])
			    		{       
			    			//deb("OK");

			    				int child1 = c1.ff , child2 = c2.ff;
			    				int col1 = c1.ss , col2 = c2.ss;

			    			//	deb("Ok");

			    				if(col1 != col2 || dp[child1][child2] != inf)
			    					continue;

			    				 dp[child1][child2] = 2 + dp[node1][node2];

			    				if(child1 != child2)
			    				{	
			    					q.push({child1,child2});
			    				//	deb(child1,child2,"Push");

			    				}
			    				else
			    				{
			    					ans = min(ans,dp[child1][child2]);
			    				//	deb(child1,child2,"2");
			    				}
			    			   
			    			  
			    		}
			    }
		}

		
		if(ans == inf)
			db(-1)
		else
			db(ans)

}

int32_t main()
{   

    LETS_GET_SCHWIFTY;

     #ifndef ONLINE_JUDGE
     freopen("INP.txt", "r", stdin);
     freopen("out.txt", "w", stdout);
     #endif  


    int t = 1;
   //cin >> t;

    while (t--)
        solve();

}

// check out for following mistakes-
// if using pb operation on vector and then trying to access index..check if sizeof that vec could remain 0 only
// is using prime sieve make sure it fits
// when using factorial template or combinatorics make sure that you edit fillfac fun values and array values

