
import java.util.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.PriorityQueue;


public class PlayerAStar {
  public static void main(String args[]) {
    Scanner in = new Scanner(System.in);
    Random rng = new Random(12);
    Instance instance = new Instance();
    AStar astar = new AStar(instance);

    instance.init(in);

    double RANDOM_PBB = 0.000;

    // game loop
    while (true) {
      instance.read(in);
      //instance.homeNode = instance.grid[399][299]; // todo uncomment to test map reachability
      long t  = System.nanoTime();
      System.err.println(String.format("Lazzie: %s isWall=%s", instance.lazzieNode, instance.walls[instance.lazzieNode.x][instance.lazzieNode.y]));
      System.err.println(String.format("Home:   %s isWall=%s", instance.homeNode, instance.walls[instance.homeNode.x][instance.homeNode.y]));

      if (rng.nextDouble()<RANDOM_PBB) {int d=rng.nextInt(4);instance.lazzieNode = instance.neighbours[instance.lazzieNode.x][instance.lazzieNode.y].get(d); System.out.println("ENSW".charAt(d)); continue;}

      astar.search(instance.lazzieNode, instance.homeNode);
      for (Node child:instance.neighbours[instance.lazzieNode.x][instance.lazzieNode.y]) //System.err.println(child);
        if (!instance.walls[child.x][child.y]) System.err.println(String.format("Dir %s:  g=%d f=%d", instance.lazzieNode.dirToNeighbour(child),(int)child.g, (int)child.f));
      instance.lazzieNode = astar.path.get(astar.path.size()-2);



      System.err.println(String.format("Path len: %d, touched: %d, time: %d", astar.path.size(), astar.touchedNum, (System.nanoTime() - t) / 1000000));
      System.out.println(astar.pathDirPrefix(20)); // Direction where Lazzie should go: N/S/W/E
    }

  }
}

class Node implements Comparable<Node>
{
  public Node parent = null;
  public int x;
  public int y;
  double g;
  double f;
  //int fromParentDir=-1;

  public Node(int x, int y)  {this.x = x; this.y = y; g = 0; f = 0; }
  //public Node(int x, int y, double delta_g) { this.x = x; this.y = y; g = delta_g; f = 0;}
  //public Node(Node n) {this.x = n.x; this.y = n.y; this.g = n.g; this.f = n.f;}

  public void reset() {g=-1; f=0; parent=null;}


  public String dirToNeighbour(Node n) {
    if (y>n.y) return "N";
    if (y<n.y) return "S";
    if (x>n.x) return "W";
    if (x<n.x) return "E";
    return "X";
  }

  @Override
  public int compareTo(Node other) {
    //if (this.f== other.f) return Double.compare(this.g, other.g);
    return Double.compare(this.f, other.f);
  }

  @Override
  public String toString()
  {
    return "Node{" +
            //"parent=" + parent +
            ", x=" + x +
            ", y=" + y +
            ", givenCost=" + g +
            ", finalCost=" + f +
            ", parent=" + (parent==null?"null":(parent.x+","+parent.y)) +
            '}';
  }
}


class AStar
{
  private Instance instance;
  private boolean[][] closed;
  private Node[] touched = new Node[4*4*4*8*1024];
  public int touchedNum;

  public Node startNode=null;
  public Node goalNode=null;
  public ArrayList<Node> path = new ArrayList<>();
  public PriorityQueue<Node> open = new PriorityQueue<>();

  public AStar(Instance instance)
  {
    this.instance = instance;
    closed = new boolean[instance.width][instance.height];
  }

  public boolean search(Node startNode, Node goalNode)
  {
    this.startNode = startNode;
    this.goalNode = goalNode;

    path.clear();
    open.clear();
    open.add(startNode);
    //for (int y=0; y < instance.height; y++) for (int x=0; x < instance.width; x++)  {closed[x][y]=false; instance.grid[x][y].reset();}
    for (int i=0; i< touchedNum; i++) {closed[touched[i].x][touched[i].y]=false; touched[i].reset();}
    touched[0]=startNode;touchedNum=1;
    instance.grid[startNode.x][startNode.y].g = 0;

    while (!open.isEmpty())
    {
      Node parent = open.poll();
      if (closed[parent.x][parent.y]) continue;
      closed[parent.x][parent.y] = true;

      if (goalNode.equals(parent))
      {
        Node n=parent; while (n!=null) {path.add(n); n=n.parent; }
        return true;
      }

      for (Node child:instance.neighbours[parent.x][parent.y])
      {
        if(instance.walls[child.x][child.y]) continue;
        if (closed[child.x][child.y]) continue;
        double ng = parent.g + instance.neighbourCost(parent, child);
        boolean newAdd = !open.contains(child);
        if (newAdd || ng < child.g)
        {
          //child = new Node(child);
          child.parent = parent;
          child.g = ng;
          child.f = child.g + instance.computeHeuristic(child, goalNode);
          if (newAdd) touched[touchedNum++]=child;
          else open.remove(child);
          open.add(child);
        }
      }
    }

    return false;
  }

  public String pathDirPrefix(int len) {
    len = Math.min(path.size()-1, len);
    if (len < 1) return "X";
    StringBuilder sb = new StringBuilder();
    for (int i=0; i<len; i++) sb.append(path.get(path.size()-i-1).dirToNeighbour(path.get(path.size()-i-2)));
    return sb.toString();
  }

}



class Instance
{

  public int visionRange;

  public boolean[][] walls;
  public Node[][] grid;
  public ArrayList<Node>[][] neighbours;

  public static int width = 500;
  public static int height = 500;
  public Node lazzieNode, homeNode;

  public static double SQRT2 = Math.sqrt(2);


  private void calculateNeighbours()
  {
    for (int y=0; y < height; y++)
    {
      for (int x=0; x < width; x++)
      {
        neighbours[x][y] = new ArrayList<>();
        if (x>0        )   neighbours[x][y].add(grid[x-1][y]);
        if (y>0        )   neighbours[x][y].add(grid[x][y-1]);
        if (y<height-1 )   neighbours[x][y].add(grid[x][y+1]);
        if (x<width-1  )   neighbours[x][y].add(grid[x+1][y]);
      }
    }
  }

  public void init(Scanner in) {
    visionRange = in.nextInt(); // Diameter of Lazzie's vision
    int homeDistanceHorizontal = in.nextInt(); // Distance in W/E direction towards home (negative means W side, positive means E side)
    int homeDistanceVertical = in.nextInt(); // Distance in N/S direction towards home (negative means N side, positive means S side)

    walls = new boolean[width][height];
    grid = new Node[width][height];
    for (int y=0; y < height; y++) for (int x=0; x < width; x++) grid[x][y] = new Node(x, y);
    lazzieNode = grid[width/2][height/2];
    homeNode = grid[width/2+homeDistanceHorizontal][height/2+homeDistanceVertical];
    neighbours = new ArrayList[width][height];
    calculateNeighbours();
  }

  public void read(Scanner in)
  {
    int radius = visionRange/2;

    for (int dy = -radius; dy <= radius; dy++)
    {
      String row = in.next(); // A single row of the map within the vision range. Possible tile values: passable terrain ('.'), impassable obstacles ('#'), outside vision circle ('?'), home entrance ('H'), Lazzie ('L').
      System.err.println(String.format("%s", row));

      for (int dx = -radius; dx <= radius; dx++)
      {
        int nx = lazzieNode.x + dx;
        int ny = lazzieNode.y + dy;
        char c = row.charAt(dx+radius);
        if (c=='#') walls[nx][ny] = true;
        if (c=='H' && (nx != homeNode.x || ny!= homeNode.y)) System.err.println(String.format("HOME ERROR! discovered %d,%d - predicted %d,%d", nx, ny, homeNode.x, homeNode.y));
      }
    }
  }

  public double neighbourCost(Node a, Node b)
  {
    return ((a.x - b.x == 0 || a.y - b.y == 0) ? 1 : SQRT2);
  }

  public double computeHeuristic(Node a, Node b)
  {
      double dx = Math.abs(a.x - b.x);
      double dy = Math.abs(a.y - b.y);
      return 1 * (dx + dy); // + (SQRT2 - 2 * 1) * Math.min(dx, dy);
  }
}



