// Arup Guha
// 4/21/2015
// Solution to Junior Knights Problem: Maze

import java.util.*;

public class maze {

    // Valid directions of movement.
    final public static int[] DX = {-1,0,0,1};
    final public static int[] DY = {0,-1,1,0};

    public static int r;
    public static int c;
    public static char[][] grid;

    public static void main(String[] args) {

        Scanner stdin = new Scanner(System.in);
        int numCases = stdin.nextInt();

        // Go through each case.
        for (int loop=0; loop<numCases; loop++) {

            // Read in the grid.
            r = stdin.nextInt();
            c = stdin.nextInt();
            grid = new char[r][];
            for (int i=0; i<r; i++)
                grid[i] = stdin.next().toCharArray();

            // Find where we are now.
            int start = getStart();

            // Run a BFS and output the result.
            System.out.println(bfs(start));
        }
    }

    public static int getStart() {

        // Search for S.
        for (int i=0; i<r; i++)
            for (int j=0; j<c; j++)
                if (grid[i][j] == 'S')
                    return i*c + j;

        // Should never get here.
        return -1;
    }

    // Runs a bfs and returns the shortest distance from loc to a border square,
    // or -1 if no such path exists.
    public static int bfs(int loc) {

        LinkedList<pair> q = new LinkedList<pair>();
        boolean[] used = new boolean[r*c];
        q.offer(new pair(loc, 0));
        used[loc] = true;

        // Start our BFS.
        while (q.size() > 0) {

            // Get next item from the queue.
            pair next = q.poll();
            int curR = next.ID/c;
            int curC = next.ID%c;

            // Made it!
            if (curR == 0 || curR == r-1 || curC == 0 || curC == c-1)
                return next.dist;

            // Enqueue all valid neighbors.
            for (int i=0; i<DX.length; i++) {

                // Here is the next spot.
                int nextR = curR + DX[i];
                int nextC = curC + DY[i];
                int nextLoc = nextR*c + nextC;

                // We can't go there if it's out of bounds, we've been there, or it's illegal.
                if (!inbounds(nextR,nextC) || used[nextLoc] || grid[nextR][nextC] == 'X') continue;

                // Put this in the queue, distance is 1 plus getting to next.
                q.offer(new pair(nextLoc, next.dist+1));
                used[nextLoc] = true;
            }
        }

        // If we get here, we never made it.
        return -1;
    }

    public static boolean inbounds(int x, int y) {
        return x >= 0 && x < r && y >= 0 && y < c;
    }
}

class pair {

    public int ID;
    public int dist;

    public pair(int index, int distance) {
        ID = index;
        dist = distance;
    };
};
