using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;

namespace AOJ
{
    public class Player
    {
        public int x;
        public int y;
        public bool move;
        //public bool goal;
        public Player(int x, int y) { 
            this.x = x;
            this.y = y;
        }
    }
    public  class Program
    {

        static char[] DIREC = { 'N', 'E', 'S', 'W' };

        private char[][] map;
        private int w, h;
        private Char rotate(char x,int n)
        {
            int d_i=0;
            for (int i = 0; i < DIREC.Length; i++)
            {
                if (DIREC[i] == x)
                {
                    d_i = i;
                    break;
                }
            }
            int[] a = {1,0,3,2};

            return DIREC[(d_i + a[n]) % 4];
        }

        private int nextX(int x, char d)
        {
            switch (d)
            {
                case 'E':
                    return x + 1;
                case 'W':
                    return x - 1;
            }
            return x;
        }
        private int nextY(int y, char d)
        {
            switch (d)
            {
                case 'N':
                    return y-1;
                case 'S':
                    return y+1;
            }
            return y;
        }

        private char nextMasu(int x, int y, char d)
        {
            char n_block = ' ';
            x = nextX(x,d);
            y = nextY(y,d);
            if(x < w && x>= 0 && y<h && y>= 0) n_block = map[y][x];

            return n_block;
        }

        private  bool canMove(int x, int y, char d)
        {
            x = nextX(x, d);
            y = nextY(y, d);

            //if (!(map[y][x] == '.') && !(map[y][x] == 'X')) return false;
            
            //優先順
            char tmp;
            if(d == 'W')return true;
            if (x < w-1) { 
                tmp = map[y][ x + 1];
                if (tmp == 'W') return false;
            }

            if (d == 'S') return true;
            if (y > 0)
            {
                tmp = map[y - 1][ x];
                if (tmp == 'S') return false;
            }

            if (d == 'E') return true;
            if (x > 0) { 
                tmp = map[y][ x - 1];
                if (tmp == 'E') return false;
            }
            return true;
        }
        private string solve(int n,int m)
        {
            map = new char[m][];
            h = m;
            w = n;

            List<Player> plist = new List<Player>();
            for (int i = 0; i < h; i++)
            {
                string s = Console.ReadLine();
                map[i] = s.ToCharArray();

                for (int j = 0; j < w; j++)
                {
                    if (map[i][j] != '.' && map[i][j] != '#' && map[i][j] != 'X')
                    {
                        Player p = new Player(j, i);
                        plist.Add(p);
                    }
                }
            }

            int hoge=0 ;
            for (int time= 0; time < 180; time++)
            {
                //向き変更
                foreach (Player p in plist)
                {
                    p.move = false;
                    for (int j = 0; j <= 3; j++)
                    {
                        char d = rotate(map[p.y][p.x], j);

                        char next = nextMasu(p.x, p.y, d);
                        if (next == '.' || next == 'X')
                        {
                            p.move = true;
                            map[p.y][p.x] = d;
                            break;
                        }
                    }
                }
                foreach(Player p in plist){
                    if (!canMove(p.x, p.y, map[p.y][p.x]))
                    {
                        p.move = false;
                    }
                }
                //移動
                for (int j = plist.Count - 1; j >= 0; j--)
                {
                    Player p = plist[j];
                    if(p.move == false)continue;

                    char d = map[p.y][p.x];
                    int nx = nextX(p.x, d);
                    int ny = nextY(p.y, d);
                    char next = map[ny][nx];

                    map[p.y][p.x] = '.';
                    
                    if (next == 'X')
                    {//goal
                        plist.RemoveAt(j);
                    }
                    else
                    {
                        map[ny][nx] = d;
                        p.x = nx;
                        p.y = ny;
                    }
                }
                ////goalした人排除
                //for (int j = plist.Count - 1; j >= 0; j--)
                //{
                //    if (plist[j].goal)
                //    {
                //        map[plist[j].y][plist[j].x] = 'X';
                //        plist.RemoveAt(j);
                //    }
                //}
                hoge++;
// print();
                if (plist.Count == 0) break;
            }
            if (plist.Count > 0) return "NA";
            return (hoge).ToString();

        }

        private void print()
        {
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++) Console.Write(map[i][j]);
                Console.WriteLine();
            }
        }
        static void Main(string[] args)
        {
            while (true)
            {
                string[] hoge = Console.ReadLine().Split(new char[] { ' ' });
                int n = int.Parse(hoge[0]);
                int m = int.Parse(hoge[1]);
                if (n == 0 && m== 0) break;

                Console.WriteLine(new Program().solve(n,m));
            }
        }
    }
}

Measured memory_bytes: 5900