#include "bits/stdc++.h"

using namespace std;
using ll = long long;
using pii = pair<int,int>;

vector<tuple<int,int,int>> edges;

void add(int x, int y, int z) {
  edges.push_back({x,y,z});
}

int solve(int l, int r) {
  if (l > 1) {
    int k = solve(1,r-l+1);
    add(k,k+1,l-1);
    return k+1;
  }
  if ((r&(-r)) == r) // r is a power of 2 
  {
    int k = __builtin_ctz(r); // Count Trailing Zeros
    add(1,2,1);
    for (int i = 3; i <= k+2; i++) {
      add(1,i,1);
      for (int j = 2; j < i; j++)
        add(j,i,1<<(j-2));
    }
    return k+2;
  }
  int k =0;
  while(1<<(k+1) <= r-1) k++;
  solve(1,1<<k);
  add(1,k+3,1);
  for (int i = 0; i <= k; i++){
    if ((r-1)>>i&1)
      add(i+2,k+3,1+((r-1)>>(i+1)<<(i+1)));
  }
  return k+3;
}

int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int l,r;
  cin >> l >> r;
  cout << "YES\n";
  int n = solve(l,r);
  cout << n << " " << edges.size() << '\n';
  for (auto [x,y,z] : edges) cout << x << " " << y << " " << z << '\n';
}

// DAG
// Good if all paths from 1 to n are between L and R
// All possible distances should be represented, once each
//
// How many different distances can I have? n nodes an give 2^n-1 paths. Always
// possible?
//
// Seems like we can do binary magic to solve
// 

