Problem: A Die Maker

The work of die makers starts early in the morning.

You are a die maker. You receive orders from customers, and make various kinds of dice every day. Today, you received an order of a cubic die with six numbers t1, t2, ..., t6 on whichever faces.

For making the ordered die, you use a tool of flat-board shape. You initially have a die with a zero on each face. If you rotate the die by 90 degrees on the tool towards one of northward, southward, eastward, and southward, the number on the face that newly touches the tool is increased by one. By rotating the die towards appropriate directions repeatedly, you may obtain the ordered die.

The final numbers on the faces of the die is determined by the sequence of directions towards which you rotate the die. We call the string that represents the sequence of directions an operation sequence. Formally, we define operation sequences as follows. An operation sequence consists of n characters, where n is the number of rotations made. If you rotate the die eastward in the i-th rotation, the i-th character of the operation sequence is `E`. Similarly, if you rotate it westward, it is `W`, if southward, it is `S`, otherwise, if northward, it is `N`. For example, the operation sequence `NWS` represents the sequence of three rotations, northward first, westward next, and finally southward.

Given six integers of the customer's order, compute an operation sequence that makes a die to order. If there are two or more possibilities, you should compute the earliest operation sequence in dictionary order.

Input

The input consists of multiple datasets. The number of datasets does not exceed 40. Each dataset has the following form.

> t1 t2 t3 t4 t5 t6
>  p q

t1, t2, ..., t6 are integers that represent the order from the customer. Further, p and q are positive integers that specify the output range of the operation sequence (see the details below).

Each dataset satisfies 0 ≤ t1 ≤ t2 ≤ ... ≤ t6 ≤ 5,000 and 1 ≤ p ≤ q ≤ t1+t2+...+t6. A line containing six zeros denotes the end of the input.

Output

For each dataset, print the subsequence, from the p-th position to the q-th position, inclusively, of the operation sequence that is the earliest in dictionary order. If it is impossible to make the ordered die, print `impossible`.

Here, dictionary order is recursively defined as follows. The empty string comes the first in dictionary order. For two nonempty strings x = x1 ... xk and y = y1 ... yl, the string x precedes the string y in dictionary order if

* x1 precedes y1 in alphabetical order ('A' to 'Z'), or
* x1 and y1 are the same character and x2 ... xk precedes y2 ... yl in dictionary order.



Sample Input


1 1 1 1 1 1
1 6
1 1 1 1 1 1
4 5
0 0 0 0 0 2
1 2
0 0 2 2 2 4
5 9
1 2 3 4 5 6
15 16
0 1 2 3 5 9
13 16
2 13 22 27 31 91
100 170
0 0 0 0 0 0


Output for the Sample Input


EEENEE
NE
impossible
NSSNW
EN
EWNS
SNSNSNSNSNSNSNSNSNSNSNSSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNWEWE






Example

Input

1 1 1 1 1 1
1 6
1 1 1 1 1 1
4 5
0 0 0 0 0 2
1 2
0 0 2 2 2 4
5 9
1 2 3 4 5 6
15 16
0 1 2 3 5 9
13 16
2 13 22 27 31 91
100 170
0 0 0 0 0 0


Output

EEENEE
NE
impossible
NSSNW
EN
EWNS
SNSNSNSNSNSNSNSNSNSNSNSSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNWEWE

Solution (in CPP):

Solution:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

struct Dice {
  int face[6];
  Dice() { MEMSET(face, 0); }
  // +Z
  int Top() const { return face[0]; }
  int &Top() { return face[0]; }
  // -Z
  int Bottom() const { return face[1]; }
  int &Bottom() { return face[1]; }
  // +X
  int Right() const { return face[2]; }
  int &Right() { return face[2]; }
  // -X
  int Left() const { return face[3]; }
  int &Left() { return face[3]; }
  // +Y
  int Front() const { return face[4]; }
  int &Front() { return face[4]; }
  // -Y
  int Back() const { return face[5]; }
  int &Back() { return face[5]; }

  Dice Rotate(int cnt, int dir) const {
    if (cnt == 0) { return *this; }
    if (cnt < 0) { cnt = cnt % 4 + 4; }
    else { cnt %= 4; }
    Dice ret;
    if (dir == 0) {
      // +X rotate(Y axis rotate)
      ret.face[0] = face[3];
      ret.face[1] = face[2];
      ret.face[2] = face[0];
      ret.face[3] = face[1];
      ret.face[4] = face[4];
      ret.face[5] = face[5];
    } else if (dir == 1) {
      // +Y rotate(X axis rotate)
      ret.face[0] = face[4];
      ret.face[1] = face[5];
      ret.face[2] = face[2];
      ret.face[3] = face[3];
      ret.face[4] = face[1];
      ret.face[5] = face[0];
    } else if (dir == 2) {
      // Z rotate(Z axis rotate)
      ret.face[0] = face[0];
      ret.face[1] = face[1];
      ret.face[2] = face[4];
      ret.face[3] = face[5];
      ret.face[4] = face[3];
      ret.face[5] = face[2];
    } else {
      assert(false);
    }
    return ret.Rotate(cnt - 1, dir);
  }
  vector<Dice> AllRotate() const {
    vector<Dice> ret;
    Dice temp = *this;
    REP(i, 6) {
      REP(j, 4) {
        ret.push_back(temp);
        temp = temp.Rotate(1, 2);
      }
      temp = temp.Rotate(1, i & 1);
    }
    return ret;
  }
  bool operator==(const Dice &rhs) const {
    REP(i, 6) { if (face[i] != rhs.face[i]) { return false; } }
    return true;
  }
  bool operator<(const Dice &rhs) const {
    REP(i, 6) {
      if (face[i] != rhs.face[i]) { return face[i] < rhs.face[i]; }
    }
    return false;
  }
};

typedef int Weight;
struct Edge {
  int src;
  int dest;
  Weight weight;
  Edge(int src, int dest, Weight weight) : src(src), dest(dest), weight(weight) {;}
  bool operator<(const Edge &rhs) const {
    if (weight != rhs.weight) { return weight > rhs.weight; }
    if (src != rhs.src) { return src < rhs.src; }
    return dest < rhs.dest;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void PrintMatrix(const Matrix &matrix) {
  for (int y = 0; y < (int)matrix.size(); y++) {
    for (int x = 0; x < (int)matrix[y].size(); x++) {
      printf("%d ", matrix[y][x]);
    }
    puts("");
  }
}

int capacity[20][20];
Weight augment(const Graph &g, const vector<int> &level, vector<bool> &finished, int from, int t, Weight cur) {
  if (from == t || cur == 0) { return cur; }
  if (finished[from]) { return 0; }
  for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
    int to = it->dest;
    if (level[to] <= level[from]) { continue; }
    Weight f = augment(g, level, finished, to, t, min(cur, capacity[from][to]));
    if (f > 0) {
      capacity[from][to] -= f;
      capacity[to][from] += f;
      return f;
    }
  }
  finished[from] = true;
  return 0;
}

Weight MaxFlow(const Graph &g, int s, int t) {
  int n = g.size();
  int ans = 0;
  while (true) {
    vector<int> level(n, -1);
    level[s] = 0;
    queue<int> que;
    que.push(s);
    for (int d = n; !que.empty() && level[que.front()] < d; ) {
      int from = que.front();
      que.pop();
      if (from == t) { d = level[from]; }
      for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
        int to = it->dest;
        if (capacity[from][to] > 0 && level[to] == -1) {
          que.push(to);
          level[to] = level[from] + 1;
        }
      }
    }
    vector<bool> finished(n);
    bool end = true;
    while (true) {
      Weight f = augment(g, level, finished, s, t, 2000000000LL);
      if (f == 0) { break; }
      ans += f;
      end = false;
    }
    if (end) { break; }
  }
  return ans;
}

void AddEdge(Graph &g, int from, int to, Weight capacity) {
  g[from].push_back(Edge(from, to, capacity));
  g[to].push_back(Edge(to, from, 0));
}

int IN(int x) { return x * 2; }
int OUT(int x) { return x * 2 + 1; }
int SOURCE() { return 12; }
int DEST() { return 13; }
int SIZE() { return 14; }
const int INF = 1e+9;

int wants[6];
int p, q;
string ans;
char str[100000];
Graph g;

void MakeGraph() {
  g = Graph(SIZE());
  REP(i, 6) {
    AddEdge(g, SOURCE(), IN(i), 0);
    AddEdge(g, OUT(i), DEST(), 0);
    REP(next, 6) {
      if (i == next || i == (next ^ 1)) { continue; }
      AddEdge(g, IN(i), OUT(next), 0);
    }
  }
}
bool ok(const Dice &now, const Dice &goal) {
  REP(end, 6) {
    int candidate = 0;
    MEMSET(capacity, 0);
    REP(i, 6) {
      int rest = goal.face[i] - now.face[i];
      // cout << "Rest: " << rest << endl;
      if (rest < 0) { return false; }
      capacity[SOURCE()][IN(i)] = rest + (i == 1 ? 1 : 0) - (i == end ? 1 : 0);
      capacity[OUT(i)][DEST()] = rest;
      candidate += rest;
      REP(next, 6) {
        if (i == next || i == (next ^ 1)) { continue; }
        capacity[IN(i)][OUT(next)] = INF;
      }
    }
    if (MaxFlow(g, SOURCE(), DEST()) == candidate) { return true; }
    // cout << "hoge" << endl;
  }
  return false;
}

int main() {
  MakeGraph();
  while (true) {
    ans = "~";
    int n = 0;
    REP(i, 6) {
      scanf("%d", &wants[i]);
      n += wants[i];
    }
    if (n == 0) { break; }
    scanf("%d %d", &p, &q);
    sort(wants, wants + 6);
    Dice dice;
    vector<Dice> goals;
    do {
      Dice goal;
      memcpy(goal.face, wants, sizeof(wants));
      if (!ok(dice, goal)) { continue; }
      goals.push_back(goal);
    } while (next_permutation(wants, wants + 6));
    if (goals.size() == 0) {
      puts("impossible");
      continue;
    }

    REP(i, n) {
      random_shuffle(goals.begin(), goals.end());
      const char dchar[4] = { 'E', 'N', 'S', 'W' };
      const int rotate[4] = { 0, 1, 1, 0 };
      const int r_cnt[4] = { 1, 1, -1, -1 };
      REP(dir, 4) {
        Dice ndice = dice.Rotate(r_cnt[dir], rotate[dir]);
        ndice.face[1]++;
        REP(j, goals.size()) {
          if (ok(ndice, goals[j].Rotate(r_cnt[dir], rotate[dir]))) {
            dice = ndice;
            // cout << j << " " << goals.size() << endl;
            goals.erase(goals.begin(), goals.begin() + j);
            FORIT(it, goals) { *it = it->Rotate(r_cnt[dir], rotate[dir]); }
            str[i] = dchar[dir];
            goto next;
          }
        }
        assert(dir != 3);
      }
next:;
    }
    ans = str;
    printf("%s\n", ans.substr(p - 1, q - p + 1).c_str());
  }
}