import java.awt.*;
import java.io.*;
import java.util.Vector;
import hsa.Console; // Debug

public class Five
{
    static Console c = new Console (); // Debug
    static Color myColor; // Debug
    static boolean IWannaSee = true; // Debug
    static int animDelay = 250; // Debug

    static char[] [] cell;
    static int[] exit = { - 1, -1};
    static Vector lastvect;
    static int minsteps = Integer.MAX_VALUE;

    public static void main (String[] args) throws IOException
    {
	c.setFont (new Font ("Courier New", Font.PLAIN, 10));

	long time = System.currentTimeMillis (); // Debug
	int i, j, k;
	BufferedReader br = new BufferedReader (new FileReader ("DATA5.txt"));

	i = Integer.parseInt (br.readLine ().trim ());
	j = Integer.parseInt (br.readLine ().trim ());
	cell = new char [j] [i];
	String temp;

	for (i = 0 ; i < cell [0].length ; i++)
	{
	    temp = br.readLine ();
	    for (j = 0 ; j < cell.length ; j++)
	    {
		cell [j] [i] = temp.charAt (j);
		// Debug
		if (cell [j] [i] == '#')
		{
		    c.setColor (Color.green);
		    c.fillRect (j * 20, i * 20, 20, 20);
		}
		else if (cell [j] [i] == 'E')
		{
		    c.setColor (Color.magenta);
		    c.fillOval (j * 20 + 7, i * 20 + 7, 6, 6);
		}
		c.setColor (Color.black);
		c.drawRect (j * 20, i * 20, 20, 20);
		// Debug
	    }
	}

	boolean[] [] moveable = new boolean [cell.length] [cell [0].length];
	int[] human = { - 1, -1}, vraptor = { - 1, -1};
	for (i = 0 ; i < cell [0].length ; i++)
	    for (j = 0 ; j < cell.length ; j++)
		if (cell [j] [i] == '#')
		    moveable [j] [i] = false;
		else
		{
		    moveable [j] [i] = true;
		    if (cell [j] [i] == '.')
		    {
		    }
		    else if (cell [j] [i] == 'E')
		    {
			exit [0] = j;
			exit [1] = i;
		    }
		    else if (cell [j] [i] == 'H')
		    {
			human [0] = j;
			human [1] = i;
		    }
		    else if (cell [j] [i] == 'V')
		    {
			vraptor [0] = j;
			vraptor [1] = i;
		    }
		}

	System.out.println ("Human - " + human [0] + ", " + human [1]); // Debug
	System.out.println ("Vraptor - " + vraptor [0] + ", " + vraptor [1]); // Debug
	System.out.println ("Exit - " + exit [0] + ", " + exit [1]); // Debug

	myColor = Color.red; // Debug
	move (vraptor [0], vraptor [1], cloneArray (moveable), new Vector ());
	minsteps = Integer.MAX_VALUE;
	System.out.println ("Vraptor calc done"); // Debug
	Vector vstep = (Vector) ((Object) (lastvect).clone ());
	myColor = Color.blue; // Debug
	move (human [0], human [1], cloneArray (moveable), new Vector ());
	System.out.println ("Human calc done"); // Debug
	Vector hstep = lastvect;

	// Debug
	int[] debug;
	System.out.println ("\nHuman steps");
	c.setColor (Color.blue);
	for (i = 0 ; i < hstep.size () ; i++) // Debug
	{
	    debug = (int[]) hstep.elementAt (i);
	    System.out.println (i + " = " + debug [0] + ", " + debug [1]);
	    c.drawString ("" + i, debug [0] * 20 + 1, 20 * (debug [1] + 1) - 1);
	}
	System.out.println ("\nVraptor steps");
	c.setColor (Color.red);
	for (i = 0 ; i < vstep.size () ; i++)
	{
	    debug = (int[]) vstep.elementAt (i);
	    System.out.println (i + " = " + debug [0] + ", " + debug [1]);
	    c.drawString ("" + (int) Math.ceil ((float) i / 2), debug [0] * 20 + 1, debug [1] * 20 + 8);
	}
	// Debug

	int answer = 0;
	boolean escape = true;
	k = 1;
	for (i = 1 ; i < hstep.size () ; i++)
	{
	    vraptor = (int[]) vstep.elementAt (k++);
	    if (vraptor [0] == human [0] && vraptor [1] == human [1])
	    {
		System.out.println ("Caught on 1st step"); // Debug
		escape = false;
		answer = i;
		break;
	    }
	    else if (vraptor [0] == exit [0] && vraptor [1] == exit [1])
	    {
		System.out.println ("Raptor reaches exit on 1st step"); // Debug
		escape = false;
		answer = hstep.size () - 1;
		break;
	    }

	    human = (int[]) hstep.elementAt (i);

	    for (j = 0 ; j < 2 ; j++)
	    {
		vraptor = (int[]) vstep.elementAt (k++);
		if (vraptor [0] == human [0] && vraptor [1] == human [1])
		{
		    System.out.println ("Caught on 2nd step"); // Debug
		    escape = false;
		    answer = i;
		    break;
		}
		else if (vraptor [0] == exit [0] && vraptor [1] == exit [1])
		{
		    System.out.println ("Raptor reaches exit on 2nd step"); // Debug
		    escape = false;
		    answer = hstep.size () - 1;
		    break;
		}
	    }
	    
	    if (human [0] == exit [0] && human [1] == exit [1])
	    {
		System.out.println ("Human safe");
		break;
	    }
	    
	    System.out.println ("Turn #" + i + ": " + human [0] + ", " + human [1] + " and " + vraptor [0] + ", " + vraptor [1]); // Debug
	}
	if (escape)
	    System.out.println ("escape");
	else
	    System.out.println (answer);

	System.out.println ("\n" + (System.currentTimeMillis () - time) + " ms"); // Debug
    }


    static boolean move (int x, int y, boolean[] [] moveable, Vector history)
    {
	// Debug
	if (IWannaSee)
	{
	    // System.out.println (x + ", " + y);
	    c.setColor (myColor);
	    c.fillOval (x * 20 + 8, y * 20 + 8, 4, 4);
	    try
	    {
		Thread.sleep (animDelay);
	    }
	    catch (Exception exc)
	    {
	    }
	    c.setColor (Color.white);
	    c.fillOval (x * 20 + 8, y * 20 + 8, 4, 4);
	}
	// Debug
	
	int[] temp = {x, y};
	history.add (temp);
	boolean keepgoing = true;
	if (x == exit [0] && y == exit [1])
	{
	    if (history.size () < minsteps)
	    {
		minsteps = history.size ();
		lastvect = history;
		return false;
	    }
	}

	moveable [x] [y] = false;

	try
	{
	    if (moveable [x - 1] [y])
		move (x - 1, y, cloneArray (moveable), (Vector) ((Object) (history).clone ()));
	}
	catch (ArrayIndexOutOfBoundsException aie)
	{
	}

	try
	{
	    if (moveable [x] [y - 1])
		move (x, y - 1, cloneArray (moveable), (Vector) ((Object) (history).clone ()));
	}
	catch (ArrayIndexOutOfBoundsException aie)
	{
	}

	try
	{
	    if (moveable [x + 1] [y])
		move (x + 1, y, cloneArray (moveable), (Vector) ((Object) (history).clone ()));
	}
	catch (ArrayIndexOutOfBoundsException aie)
	{
	}

	try
	{
	    if (moveable [x] [y + 1])
		move (x, y + 1, cloneArray (moveable), (Vector) ((Object) (history).clone ()));
	}
	catch (ArrayIndexOutOfBoundsException aie)
	{
	}

	return true;
    }


    static boolean[] [] cloneArray (boolean[] [] array)
    {
	boolean[] [] clone = new boolean [array.length] [array [0].length];
	for (int i = 0 ; i < array.length ; i++)
	    for (int j = 0 ; j < array [i].length ; j++)
		clone [i] [j] = array [i] [j];
	return clone;
    }
}


