#include <assert.h>
#include <iostream.h>

int north(int val) { assert(val>9); return(val-10); }
int south(int val) { assert(val<90); return(val+10); }
int east(int val) { assert(val%10!=9); return(val+1); }
int west(int val) { assert(val%10!=0); return(val-1); }
bool northp(int val) { return(val>9); }
bool southp(int val) { return(val<90); }
bool eastp(int val) { return(val%10!=9); }
bool westp(int val) { return(val%10!=0); }

int cts[100];  // -1 for bend, 1 for straight

int path[100];
int used[100];

bool temp[100];
void cutrecurse(int pos) {
  temp[pos] = true;
  if (eastp(pos) && !temp[east(pos)]) cutrecurse(east(pos));
  if (westp(pos) && !temp[west(pos)]) cutrecurse(west(pos));
  if (northp(pos) && !temp[north(pos)]) cutrecurse(north(pos));
  if (southp(pos) && !temp[south(pos)]) cutrecurse(south(pos));
}
bool singlet(int pos, int spos) {
  if (pos == 10) return false;
  int chi=0;
  if (eastp(pos) && (!temp[east(pos)] || east(pos)==spos)) chi++;
  if (westp(pos) && (!temp[west(pos)] || west(pos)==spos)) chi++;
  if (northp(pos) && (!temp[north(pos)] || north(pos)==spos)) chi++;
  if (southp(pos) && (!temp[south(pos)] || south(pos)==spos)) chi++;
  return (chi < 2); 
}
bool cutted(int count) {
  if (count > 90) return false;
  for (int i=0;i<100;i++) {
    temp[i] = false;
  }
  for (int i=0;i<=count;i++) {
    temp[path[i]] = true; 
  }
  for (int i=0;i<100;i++) {
    if (!temp[i] && singlet(i,path[count])) {
      return(true);
    }
  }
  int found = -1;
  for (int i=0;i<100;i++) {
    if (!temp[i]) {
      found = i;
      break;
    }
  }
  cutrecurse(found);
  for (int i=0;i<100;i++) {
    if (!temp[i]) {
      return true;
    }
  }
  return false;
}

bool cose(int a, int b) {
  if (a+1==b) return true;
  if (b+1==a) return true;
  return false;
}

char rep(int pos) {
  if (used[pos] == -1) return '.';
  bool adj[4]; // 0=west, 1=east, 2=north, 3=south
  adj[0] = false; adj[1] = false; adj[2] = false; adj[3] = false;
  if (westp(pos) && cose(used[west(pos)],used[pos])) adj[0] = true;
  if (eastp(pos) && cose(used[east(pos)],used[pos])) adj[1] = true;
  if (northp(pos) && cose(used[north(pos)],used[pos])) adj[2] = true;
  if (southp(pos) && cose(used[south(pos)],used[pos])) adj[3] = true;
  if (adj[0] && adj[1]) return '-';
  if (adj[0] && adj[2]) return 'J';
  if (adj[0] && adj[3]) return 'T';
  if (adj[1] && adj[2]) return 'L';
  if (adj[1] && adj[3]) return 'F';
  if (adj[2] && adj[3]) return '|';
  return 'x'; 
}

void print() {
  for (int i=0; i<10; i++) {
    for (int j=0; j<10; j++) {
      cout << rep(i*10+j);
    }
    cout << "\n";
  }
}

int ter = 0;

void recurse(int count, int pos, int dir) {
  // dir: 0=east, 1=west, 2=south, 3=north
  if (pos == 10 && count < 95) return;
  ter++;
  if (ter > 20000) {
    ter = 0;
    print();  cout << "\n";
  }
  if (cutted(count)) return;
  if (count == 99) {
    if (pos == 10) { 
      cout << "yay!\n";
      print();
    }
    return;
  } 
  bool tries[4]; // 0=west, 1=east, 2=north, 3=south
  tries[0] = true; tries[1] = true; tries[2] = true; tries[3] = true;
  tries[dir] = false;  // don't doubleback
  if (cts[pos] == -1 && dir == 0) tries[1] = false;
  if (cts[pos] == -1 && dir == 1) tries[0] = false;
  if (cts[pos] == -1 && dir == 2) tries[3] = false;
  if (cts[pos] == -1 && dir == 3) tries[2] = false;
  if (cts[pos] == 1 && dir < 2) tries[2] = false;
  if (cts[pos] == 1 && dir < 2) tries[3] = false;
  if (cts[pos] == 1 && dir > 1) tries[0] = false;
  if (cts[pos] == 1 && dir > 1) tries[1] = false;
  if (tries[0] && westp(pos) && used[west(pos)] == -1) {
    path[count+1]=west(pos); used[west(pos)] = count+1;
    recurse(count+1,west(pos),1); used[west(pos)] = -1;
  }
  if (tries[2] && northp(pos) && used[north(pos)] == -1) {
    path[count+1]=north(pos); used[north(pos)] = count+1;
    recurse(count+1,north(pos),3); used[north(pos)] = -1;
  }
  if (tries[3] && southp(pos) && used[south(pos)] == -1) {
    path[count+1]=south(pos); used[south(pos)] = count+1;
    recurse(count+1,south(pos),2); used[south(pos)] = -1;
  }
  if (tries[1] && eastp(pos) && used[east(pos)] == -1) {
    path[count+1]=east(pos); used[east(pos)] = count+1;
    recurse(count+1,east(pos),0); used[east(pos)] = -1;
  }
}

void main() {
  for (int i=0;i<100;i++) {
    cts[i] = 0;
    path[i] = -1;
    used[i] = -1;
  }
  cts[12] = 1; cts[15] = -1; cts[18] = -1; 
  cts[38] = -1; cts[36] = -1; cts[56] = -1; cts[58] = -1;
  cts[54] = -1; cts[53] = -1; cts[42] = -1;
  cts[67] = -1; cts[78] = -1; cts[88] = -1;
  cts[74] = -1; cts[84] = -1;
  cts[14] = 1; cts[16] = 1;
  cts[27] = 1; cts[25] = 1; cts[23] = 1; cts[21] = 1;
  cts[31] = 1; cts[43] = 1;
  cts[34] = 1; cts[45] = 1; cts[47] = 1;
  cts[51] = 1; cts[62] = 1; cts[71] = 1; cts[73] = 1; 
  cts[82] = 1;
  cts[65] = 1; cts[76] = 1; cts[87] = 1; cts[85] = 1;

  path[0] = 0; used[0] = 0;
  path[1] = 1; used[1] = 1;
  recurse(1,1,0);
}

