/**
* 搜索题 BFS:
* 关键就是 状态转移,和判重。
* 这里用isVis[i][j]表示之前搜索的时候是否访问过a桶和b桶存有i j升水
* 如果访问过则不再加入队列。 因为题目要求的是最短路径,如果再次访问,
* 所需操作次数必然更大,所以当第一次访问的时候就要设vis的值为1表示已访问。
* 答案输出我用的是stack栈去存储。 因为之前在每次放入队列的时候都记录了前一个状态。
* Node结构体的设计: a, b 分别表示两桶存的水量
* prePos 之前一个状态的下标
* type 是之前一个状态到当前状态所采取的的操作类型
* 12表示 POUR(1,2) 21 反之
* 1 表示 FILL a 2 亦同
* 10表示 DROP a 20 亦同 ———— 1A
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#define INF 0x7fffffff
#define MAXS 10010
#define LL long long
using namespace std;
struct Node {
int a, b;
int prePos, type; // 12 21 1 2 10 20
} nodes[MAXS];
int oriA, oriB, des;
int ansStack[101], top, rear, front;
int isVis[101][101];
void print() {
printf("%d\n", top);
top --;
while(top != -1) {
if(ansStack[top] == 1)
printf("FILL(1)\n");
else if(ansStack[top] == 2)
printf("FILL(2)\n");
else if(ansStack[top] == 12)
printf("POUR(1,2)\n");
else if(ansStack[top] == 21)
printf("POUR(2,1)\n");
else if(ansStack[top] == 10)
printf("DROP(1)\n");
else if(ansStack[top] == 20)
printf("DROP(2)\n");
top --;
}
}
int main()
{
while(scanf("%d%d%d", &oriA, &oriB, &des) != EOF) {
int a, b, ans, found;
a = b = rear = found = top = 0;
front = 0;
memset(isVis, 0, sizeof(isVis));
isVis[0][0] = 1;
Node newNode;
newNode.a = newNode.b = 0;
newNode.prePos = ans = -1;
nodes[rear++] = newNode;
while(front < rear && !found) {
//int curPre = front;
newNode = nodes[front];
newNode.prePos = front;
if(newNode.a == des || newNode.b == des) {
found = 1;
ans = front;
break;
}
// drop a
if(newNode.a && !isVis[0][newNode.b]) {
newNode.a = 0;
newNode.type = 10;
nodes[rear++] = newNode;
isVis[0][newNode.b] = 1;
newNode.a = nodes[front].a;
}
// drop b
if(newNode.b && !isVis[newNode.a][0]) {
newNode.b = 0;
newNode.type = 20;
nodes[rear++] = newNode;
isVis[newNode.a][0] = 1;
newNode.b = nodes[front].b;
}
// fill a
if(newNode.a != oriA && !isVis[oriA][newNode.b]) {
newNode.a = oriA;
newNode.type = 1;
nodes[rear++] = newNode;
isVis[oriA][newNode.b] = 1;
newNode.a = nodes[front].a;
}
// fill b
if(newNode.b != oriB && !isVis[newNode.a][oriB]) {
newNode.b = oriB;
newNode.type = 2;
nodes[rear++] = newNode;
isVis[newNode.a][oriB] = 1;
newNode.b = nodes[front].b;
}
// pour a to b
if(newNode.a && newNode.b != oriB) {
newNode.b += newNode.a;
newNode.a = 0;
if(newNode.b > oriB) {
newNode.a = newNode.b - oriB;
newNode.b = oriB;
}
if(!isVis[newNode.a][newNode.b]) {
newNode.type = 12;
nodes[rear++] = newNode;
isVis[newNode.a][newNode.b] = 1;
}
newNode.a = nodes[front].a;
newNode.b = nodes[front].b;
}
// pour b to a
if(newNode.b && newNode.a != oriA) {
newNode.a += newNode.b;
newNode.b = 0;
if(newNode.a > oriA) {
newNode.b = newNode.a - oriA;
newNode.a = oriA;
}
if(!isVis[newNode.a][newNode.b]) {
newNode.type = 21;
nodes[rear++] = newNode;
isVis[newNode.a][newNode.b] = 1;
}
newNode.a = nodes[front].a;
newNode.b = nodes[front].b;
}
front ++;
}
if(ans == -1) {
printf("impossible\n");
continue;
}
while(nodes[ans].prePos != -1) {
ansStack[top++] = nodes[ans].type;
ans = nodes[ans].prePos;
}
print();
}
return 0;
}