@file:Suppress("NOTHING_TO_INLINE", "EXPERIMENTAL_FEATURE_WARNING", "OVERRIDE_BY_INLINE")
//@file:OptIn(ExperimentalStdlibApi::class)

import java.io.PrintWriter
import kotlin.math.*
import kotlin.random.Random
import kotlin.collections.sort as _sort
import kotlin.collections.sortDescending as _sortDescending
import kotlin.io.println as iprintln

/** @author Spheniscine */
fun main() { _writer.solve(); _writer.flush() }
fun PrintWriter.solve() {
//    val startTime = System.nanoTime()

    val numCases = 1//readInt()
    case@ for(case in 1..numCases) {
//        print("Case #$case: ")

        object {
            val debug = LongArray(N).also { debug ->
                debug[A] = 2
                debug[B] = 3
            }

            val ops = mutableListOf<String>()

            fun add(i: Int, j: Int, k: Int) {
                ops.add("+ $i $j $k")
                debug[k] = debug[i] + debug[j]
            }

            fun lt(i: Int, j: Int, k: Int) {
                ops.add("< $i $j $k")
                debug[k] = if(debug[i] < debug[j]) 1 else 0
            }

            var allocp = 3
            var stackp = N-1

            fun alloc() = allocp++
            fun alloc(size: Int) = RegArr(allocp, size).also { allocp += size }

            fun allocStk() = stackp--
            inline fun <R> onStack(func: () -> R): R {
                val stack = stackp
                return func().also { stackp = stack }
            }

            val zero = alloc()
            fun set0(i: Int) { lt(i, i, i) }
            fun cpy(i: Int, j: Int) { add(i, zero, j) }
            fun set1(i: Int) {
                add(A, B, i)
                lt(zero, i, i)
            }

            val bits = alloc(30).also { bits ->
                set1(bits[0])

                for(i in 1 until bits.size) {
                    add(bits[i-1], bits[i-1], bits[i])
                }
            }
            val one = bits[0]

            fun leq(i: Int, j: Int, k: Int) {
                onStack {
                    val tmp = allocStk()
                    add(j, one, tmp)
                    lt(i, tmp, k)
                }
            }

            fun dcmp(a: Int, res: RegArr = alloc(bits.size)): RegArr = onStack {
                val curr = allocStk()
                set0(curr)
                val a1 = allocStk()
                add(a, one, a1)
                val cmp = allocStk()
                val tmp = allocStk()

                for(i in bits.indices.reversed()) {
                    add(bits[i], curr, cmp)
                    lt(cmp, a1, res[i])
                    cpy(res[i], tmp)
                    repeat(i) {
                        add(tmp, tmp, tmp)
                    }
                    add(tmp, curr, curr)
                }

                res
            }

            val abits = dcmp(A)
            val bbits = dcmp(B)

            fun and(i: Int, j: Int, k: Int) {
                add(i, j, k)
                lt(one, k, k)
            }

            fun solve() {
                onStack {
                    val tmp = allocStk()

                    for(k in (abits.size - 1) * 2 downTo 0) {
                        add(ans, ans, ans)
                        for(i in 0 .. k) {
                            val j = k - i
                            if(i in abits.indices && j in bbits.indices) {
                                and(abits[i], bbits[j], tmp)
                                add(ans, tmp, ans)
                            }
                        }
                    }
                }


                println(ops.size)
                ops.forEach(::println)
            }
        }.solve()
    }

//    iprintln("Time: ${(System.nanoTime() - startTime) / 1000000} ms")
}

const val N = 200000
const val Q = N
const val A = 0
const val B = 1
const val ans = 2

data class RegArr(val start: Int, val size: Int) {
    operator fun get(i: Int) = start + i
    val indices get() = 0 until size
    operator fun iterator() = (start until start + size).iterator()
}

/** IO */
//@JvmField val INPUT = File("input.txt").inputStream()
//@JvmField val OUTPUT = File("output.txt").outputStream()
@JvmField val INPUT = System.`in`
@JvmField val OUTPUT = System.out

const val _BUFFER_SIZE = 1 shl 16
@JvmField val _buffer = ByteArray(_BUFFER_SIZE)
@JvmField var _bufferPt = 0
@JvmField var _bytesRead = 0

tailrec fun readChar(): Char {
    if(_bufferPt == _bytesRead) {
        _bufferPt = 0
        _bytesRead = INPUT.read(_buffer, 0, _BUFFER_SIZE)
    }
    return if(_bytesRead < 0) Char.MIN_VALUE
    else {
        val c = _buffer[_bufferPt++].toChar()
        if (c == '\r') readChar()
        else c
    }
}

fun readLine(): String? {
    var c = readChar()
    return if(c == Char.MIN_VALUE) null
    else buildString {
        while(c != '\n' && c != Char.MIN_VALUE) {
            append(c)
            c = readChar()
        }
    }
}
fun readLn() = readLine()!!

fun read() = buildString {
    var c = readChar()
    while(c <= ' ') {
        if(c == Char.MIN_VALUE) return@buildString
        c = readChar()
    }
    do {
        append(c)
        c = readChar()
    } while(c > ' ')
}
fun readInt() = read().toInt()
fun readDouble() = read().toDouble()
fun readLong() = read().toLong()
fun readStrings(n: Int) = List(n) { read() }
fun readLines(n: Int) = List(n) { readLn() }
fun readInts(n: Int) = List(n) { read().toInt() }
fun readIntArray(n: Int) = IntArray(n) { read().toInt() }
fun readDoubles(n: Int) = List(n) { read().toDouble() }
fun readDoubleArray(n: Int) = DoubleArray(n) { read().toDouble() }
fun readLongs(n: Int) = List(n) { read().toLong() }
fun readLongArray(n: Int) = LongArray(n) { read().toLong() }

@JvmField val _writer = PrintWriter(OUTPUT, false)

/** shuffles and sort overrides to avoid quicksort attacks */
private inline fun <T> _shuffle(rnd: Random, get: (Int) -> T, set: (Int, T) -> Unit, size: Int) {
    // Fisher-Yates shuffle algorithm
    for (i in size - 1 downTo 1) {
        val j = rnd.nextInt(i + 1)
        val temp = get(i)
        set(i, get(j))
        set(j, temp)
    }
}

@JvmField var _random: Random? = null
val random get() = _random ?: Random(0x594E215C123 * System.nanoTime()).also { _random = it }

fun IntArray.shuffle(rnd: Random = random) = _shuffle(rnd, ::get, ::set, size)
fun IntArray.sort() { shuffle(); _sort() }
fun IntArray.sortDescending() { shuffle(); _sortDescending() }

fun LongArray.shuffle(rnd: Random = random) = _shuffle(rnd, ::get, ::set, size)
fun LongArray.sort() { shuffle(); _sort() }
fun LongArray.sortDescending() { shuffle(); _sortDescending() }

fun DoubleArray.shuffle(rnd: Random = random) = _shuffle(rnd, ::get, ::set, size)
fun DoubleArray.sort() { shuffle(); _sort() }
fun DoubleArray.sortDescending() { shuffle(); _sortDescending() }

fun CharArray.shuffle(rnd: Random = random) = _shuffle(rnd, ::get, ::set, size)
inline fun CharArray.sort() { _sort() }
inline fun CharArray.sortDescending() { _sortDescending() }

inline fun <T: Comparable<T>> Array<out T>.sort() = _sort()
inline fun <T: Comparable<T>> Array<out T>.sortDescending() = _sortDescending()
inline fun <T: Comparable<T>> MutableList<out T>.sort() = _sort()
inline fun <T: Comparable<T>> MutableList<out T>.sortDescending() = _sortDescending()

fun `please stop removing these imports IntelliJ`() { iprintln(max(1, 2)) }

/** additional commons */
inline fun <T> Iterable<T>.sumByLong(func: (T) -> Long) = fold(0L) { acc, t -> acc + func(t) }
inline fun <T> Sequence<T>.sumByLong(func: (T) -> Long) = fold(0L) { acc, t -> acc + func(t) }
inline fun <T> Array<T>.sumByLong(func: (T) -> Long) = fold(0L) { acc, t -> acc + func(t) }
fun IntArray.sumLong() = fold(0L, Long::plus)


Measured memory_bytes: 38868