Problem: This is an output-only problem. You shouldn't read anything from the input.

In short, your task is to simulate multiplication by using only comparison (x < y) and addition (x + y). There is no input in this problem, you just print a sequence of operations.

Imagine that there is a big array a[0], a[1], ..., a[N-1] of length N. The first two values are initially two non-negative integers A and B (which are unknown to you), the other elements are zeros. Your goal is to get the product A \cdot B in a[2] at the end.

You are allowed operations of two types, with the following format (where 0 \leq i, j, k < N):

* `+ i j k` — applies operation a[k] = a[i] + a[j].
* `< i j k` — applies operation a[k] = a[i] < a[j]. That is, if a[i] < a[j] then a[k] becomes 1, otherwise it becomes 0.



You can use at most Q operations. Elements of a can't exceed V. Indices (i, j, k) don't have to be distinct. It's allowed to modify any element of the array (including the first two). The actual checker simulates the process for multiple pairs (A, B) within a single test. Each time, the checker chooses values A and B, creates the array a = [A, B, 0, 0, \ldots, 0], applies all your operations and ensures that a[2] = A \cdot B.

Constraints

* 0 \leq A, B \leq 10^9
* N = Q = 200\,000
* V = 10^{19} = 10\,000\,000\,000\,000\,000\,000

Input

The Standard Input is empty.

Output

In the first line, print the number of operations. Each operation should then be printed in a single line of format `+ i j k` or `< i j k`.

Example

Input




Output

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair < int , int > pii;
#define mpr make_pair
#define FS first
#define SC second
#define PB push_back
template < typename T > T MAX(T a,T b){return (a>b)?a:b;}
template < typename T > T MIN(T a,T b){return (a<b)?a:b;}
template < typename T > void UMAX(T &a,T b){a=(a>b?a:b);}
template < typename T > void UMIN(T &a,T b){a=(a<b?a:b);}
LL readint(){
	char c=getchar();
	LL ret=0ll;
	bool neg=0;
	while(!(c>='0' && c<='9')){
		if(c=='-') neg=1;
		c=getchar();
	}
	while(c>='0' && c<='9'){
		ret=ret*10ll+(LL)(c-'0');
		c=getchar();
	}
	return neg?-ret:ret;
}
void putint(LL v){
	if(v<0){
		putchar('-');
		v=-v;
	}
	if(!v){
		putchar('0');
		return;
	}
	if(v>=10ll) putint(v/10ll);
	putchar('0'+(v%10ll));
}
map < int , LL > mem;
int ptr=13,A=0,B=1,zero=10,one=11,two=12;
vector < string > out;
void add(int a,int b,int t){
//	mem[t]=mem[a]+mem[b];
	char s[50]={};
	sprintf(s,"+ %d %d %d\n",a,b,t);
	out.push_back(string(s));
}
void cmp(int a,int b,int t){
//	mem[t]=mem[a]<mem[b];
	char s[50]={};
	sprintf(s,"< %d %d %d\n",a,b,t);
	out.push_back(string(s));
}
void ass(int s,int t){
	add(s,zero,t);
}
int opr_and(int u,int v,int w=ptr++){
	int tmp=ptr++;
	add(u,v,tmp);
	cmp(one,tmp,w);
	return w;
}
void left_shift_by_k(int a,int k){
	int i;
	for(i=0;i<k;++i) add(a,a,a);
}
vector < int > decomp(int u){
	int i,j,k;
	vector < int > pws(31);
	for(i=0;i<=30;++i) pws[i]=ptr++;
	ass(one,pws[0]);
	for(i=1;i<=30;++i){
		add(pws[i-1],pws[i-1],pws[i]);
	}
	vector < int > ret(31);
	for(i=0;i<=30;++i) ret[i]=ptr++;
	int got=ptr++;
	for(i=30;i>=0;--i){
		int cur=ptr++;
		for(j=0;j<i;++j) add(cur,pws[j],cur);
		add(cur,got,cur);
		int cmpv=ptr++;
		cmp(cur,u,cmpv);
//		printf("cmp %lld %lld %lld\n",mem[cur],mem[u],mem[cmpv]);
		ass(cmpv,ret[i]);
		left_shift_by_k(cmpv,i);
		add(got,cmpv,got);
	}
	return ret;
}
#define initialization_confirm
#define corner_case_check
#define return_type_of_template_and_operator
int main(){
	#ifdef LOCAL_QTY
		#ifndef initialization_confirm // 不要忘记初始化
			exit(0);
		#endif
		#ifndef corner_case_check // 不要忘记检查边界情况（图不连通，n=1，etc.）
			exit(0);
		#endif
		#ifndef return_type_of_template_and_operator // 勿忘返回值类型
			exit(0);
		#endif
	#endif
	int i,j,k;
//	cin>>mem[A]>>mem[B];
	add(A,B,3);
	cmp(zero,3,one);
	add(one,one,two);
	vector < int > dA=decomp(A),dB=decomp(B);
//	for(i=0;i<31;++i) cout<<mem[dA[i]];
//	cout<<endl;
//	for(i=0;i<31;++i) cout<<mem[dB[i]];
//	cout<<endl;
	vector < int > res(62);
	for(i=0;i<62;++i) res[i]=ptr++;
	for(i=0;i<31;++i){
		for(j=0;j<31;++j){
			add(res[i+j],opr_and(dA[i],dB[j]),res[i+j]);
		}
	}
	for(i=0;i<62;++i){
		left_shift_by_k(res[i],i);
		add(2,res[i],2);
	}
//	cout<<mem[2]<<endl;
//	printf("%d\n",ptr);
	printf("%d\n",(int)out.size());
	for(i=0;i<(int)out.size();++i){
		printf("%s",out[i].c_str());
	}
	return 0;
}
/*
 * 代码框架
 * 1. ptr维护已经用过的位置
 * 2. 实现and，参数为原坐标，返回新坐标
 * 3. 实现二进制分解，参数为原坐标，返回vector表示坐标列表
 * 4. 将两个数二进制分解
 * 5. 两两枚举位，把and的结果加到对应位上
 * 6. 不断进行a=(2a+cur)的操作，得到结果
*/