#include <stdio.h>

struct node {
	node * l, * r;
	int v;
};

struct iter {
	node * n;
	int step;
};

void insert(node *& tree, int v)
{
	if (! tree) {
		tree = new node;
		tree->v = v;
		tree->l = NULL;
		tree->r = NULL;
	} else if (v < tree->v) {
		insert(tree->l, v);
	} else {
		insert(tree->r, v);
	}
}

void iter_push(iter *&it, int & sp, node * n)
{
	it[sp].n = n;
	it[sp].step = 0;
	sp++;
}

//	pre(node):
//		0: pre(node->l)
//		1: yield node->v
//		2: pre(node->r)
node * do_iter(iter *& it, int & sp, bool pre)
{
	while (sp > 0) {
		node * n;
		iter & i = it[sp-1];
		switch (i.step) {
		case 0:
			i.step = 1;
			n = pre ? i.n->l : i.n->r;
			if (n) iter_push(it, sp, n);
			break;
		case 1:
			i.step = 2;
			return i.n;
		case 2:
			i.step = 3;
			n = pre ? i.n->r : i.n->l;
			if (n) iter_push(it, sp, n);
			break;
		case 3:
			sp--;
			break;
		}
	}
	return NULL;
}

#define iter_pre( it, sp) do_iter(it, sp, true)
#define iter_post(it, sp) do_iter(it, sp, false)

int main(int argc, char * argv[])
{
	if (! freopen((argc>1) ? argv[1] : "debug\\test\\1.in", "r", stdin))
		return 0;

	int n, c;
	scanf("%d%d", &n, &c);
	node * tree = NULL;
	for (int i=0; i<n; i++) {
		int v;
		scanf("%d", &v);
		insert(tree, v);
	}
	
	iter * i1 = new iter[n];
	iter * i2 = new iter[n];
	int sp1=0, sp2=0;
	
	iter_push(i1, sp1, tree);
	iter_push(i2, sp2, tree);
	
	node * a, * b;
	
	b = iter_post(i2, sp2);
	while ((a = iter_pre(i1, sp1))) {
		while (b && a->v + b->v > c)
			b = iter_post(i2, sp2);
		if (b && a->v + b->v == c)
			printf("%d+%d=%d\n", a->v, b->v, c);
	}

	return 0;
}
