#include <bits/stdc++.h>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

struct Road {
    int a, b, c;
};


// check
const int MAXC = 1e6 + 1;
int vis[MAXC];
vector<pii> g[33];

void dfs(int n, int a, int x) {
    if (a == n) {
        vis[x]++;
        return;
    }
    for (auto const &[b, c] : g[a]) {
        dfs(n, b, x+c);
    }
}


bool check(int n, int L, int R, const vector<Road> &answer) {
    for (auto const &[a, b, c] : answer) {
        g[a].push_back({b, c});
    }
    dfs(n, 1, 0);
    for (int x = 0; x < MAXC; x++) {
        if (x < L || x > R) {
            if (vis[x]) return false;
        } else {
            if (vis[x] != 1) return false;
        }
    }
    return true;
}

//

int oL, oR;
int L, R;
int n = 32;

int main() {
    scanf("%d%d",&oL,&oR);
    L = oL, R = oR;
    vector<Road> answer;
    int offset = L-1;
    L -= offset, R -= offset;
    auto add_edge = [&](int a, int b, int c) {
        if (a == 1) c += offset;
        assert(a < b);
        assert(c >= 1);
        if (c <= 1e6)
            answer.push_back({a, b, c});
    };

    L++;
    add_edge(1, n, 1);
    for (int a = n-1; a > 1; a--) {
        add_edge(a, n, 1);
        for (int b = n-1, z = 1; b > a; b--, z <<= 1) {
            add_edge(a, b, z);
        }
    }
    int num = R-L+1, z=1;
    for (int a = n-1, block = 1; a > 1; a--, block <<= 1) {
        if (num % 2) {
            add_edge(1, a, z);
            z += block;
        }
        num >>= 1;
    }
    int m = int(answer.size());
    printf("YES\n%d %d\n", n, m);
    for (auto const& [a, b, c] : answer) {
        printf("%d %d %d\n", a, b, c);
    }

    assert(check(n, oL, oR, answer));
}
