#ifdef DBG1
#define _GLIBCXX_DEBUG
#endif

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <functional>

#ifdef DBG1
#define dbg(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#else
#define dbg(...)
#endif

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, int> pli;

const int P = 200003;

int sum(int a, int b) {
  if ((a += b) >= P) {
    a -= P;
  }
  return a;
}

int diff(int a, int b) {
  if ((a -= b) < 0) {
    a += P;
  }
  return a;
}

int prod(int a, int b) {
  return int(ll(a) * b % P);
}

int power(int a, int n) {
  int b = 1;
  while (n) {
    if (n & 1) { b = prod(a, b); }
    a = prod(a, a);
    n /= 2;
  }
  return b;
}

int inv(int a) {
  return power(a, P - 2);
}

int quotient(int a, int b) {
  return prod(a, inv(b));
}

int &add(int &a, int b) {
  return a = sum(a, b);
}

int &subtract(int &a, int b) {
  return a = diff(a, b);
}

int &mult(int &a, int b) {
  return a = prod(a, b);
}

int &div(int &a, int b) {
  return a = quotient(a, b);
}

enum OpType {
  PLUS,
  LESS
};

struct Op {
  OpType type;
  int i, j, k;
};

vector<Op> solve() {
  vector<Op> ops;
  // A B 0 ... 0
  int regs = 3;
  int A = 0;
  int B = 1;
  int RES = 2;

  auto ZERO = regs++;
  auto ONE = regs++;
  ops.push_back({LESS, ZERO, A, ONE});

  ops.push_back({PLUS, A, ONE, A});
  ops.push_back({PLUS, B, ONE, B});

  vector<int> pow2(30);
  pow2[0] = ONE;
  for (int i = 1; i < (int)pow2.size(); ++i) {
    pow2[i] = regs++;
    ops.push_back({PLUS, pow2[i - 1], pow2[i - 1], pow2[i]});
  }

  int tmp1 = regs++;
  int tmp2 = regs++;
  int tmp3 = regs++;
  int tmp4 = regs++;
  auto split_to_bits = [&](int A) -> vector<int> {
    vector<int> bits(pow2.size());
    int made = regs++;
    for (int i = pow2.size() - 1; i >= 0; --i) {
      ops.push_back({PLUS, made, pow2[i], tmp1});
      ops.push_back({LESS, tmp1, A, tmp2});
      bits[i] = regs++;
      ops.push_back({PLUS, bits[i], tmp2, bits[i]});
      for (int j = 0; j < i; ++j) {
        ops.push_back({PLUS, tmp2, tmp2, tmp2});
      }
      ops.push_back({PLUS, made, tmp2, made});
    }
//    ops.push_back({PLUS, RES, made, RES});
    return bits;
  };

  auto abits = split_to_bits(A);
  auto bbits = split_to_bits(B);

  for (int i = 0; i < (int)pow2.size(); ++i) {
    for (int j = 0; j < (int)pow2.size(); ++j) {
      ops.push_back({LESS, abits[i], ONE, tmp1});
      ops.push_back({LESS, bbits[j], ONE, tmp2});
      ops.push_back({PLUS, tmp1, tmp2, tmp3});
      ops.push_back({LESS, tmp3, ONE, tmp4});
      for (int k = 0; k < i + j; ++k) {
        ops.push_back({PLUS, tmp4, tmp4, tmp4});
      }
      ops.push_back({PLUS, RES, tmp4, RES});
    }
  }

  return ops;
}

#ifdef DBG1
void run(const vector<Op> &ops, ll A, ll B, bool debug) {
  vector<ll> regs(200000);
  regs[0] = A;
  regs[1] = B;
  for (const auto op : ops) {
    if (op.type == PLUS) {
      regs[op.k] = regs[op.i] + regs[op.j];
      if (debug) printf("regs[%d] = regs[%d] + regs[%d]\n", op.i, op.j, op.k);
    } else if (op.type == LESS) {
      regs[op.k] = (regs[op.i] < regs[op.j] ? 1 : 0);
      if (debug) printf("regs[%d] = regs[%d] < regs[%d]\n", op.i, op.j, op.k);
    } else {
      assert(0);
    }
    if (debug) {
      for (int i = 0; i < 100; ++i) {
        printf("%lld ", regs[i]);
      }
      printf("\n");
    }
  }
  if (debug) dbg("ops count %d\n", (int)ops.size());
  assert(regs[2] == A * B);
}
#endif

int main() {
  vector<Op> ops = solve();
  printf("%d\n", (int)ops.size());
  for (const auto & op : ops) {
    if (op.type == PLUS) {
      printf("+ %d %d %d\n", op.i, op.j, op.k);
    } else if (op.type == LESS) {
      printf("< %d %d %d\n", op.i, op.j, op.k);
    }
  }
#ifdef DBG1
  for (int a = 0; a <= 100; ++a) {
    for (int b = 0; b <= 100; ++b) {
      run(ops, a, b, false);
    }
  }
#endif
  return 0;
}


Measured memory_bytes: 3768