Problem:
Score : 200 points

Problem Statement

#nck {
width: 30px;
height: auto;
}

We have a grid of H rows and W columns. Initially, there is a stone in the top left cell. Shik is trying to move the stone to the bottom right cell. In each step, he can move the stone one cell to its left, up, right, or down (if such cell exists). It is possible that the stone visits a cell multiple times (including the bottom right and the top left cell).

You are given a matrix of characters a_{ij} (1 \leq i \leq H, 1 \leq j \leq W). After Shik completes all moving actions, a_{ij} is # if the stone had ever located at the i-th row and the j-th column during the process of moving. Otherwise, a_{ij} is .. Please determine whether it is possible that Shik only uses right and down moves in all steps.

Constraints

2 \leq H, W \leq 8

a_{i,j} is either # or ..

There exists a valid sequence of moves for Shik to generate the map a.

Input

The input is given from Standard Input in the following format:

H W
a_{11}a_{12}...a_{1W}
:
a_{H1}a_{H2}...a_{HW}

Output

If it is possible that Shik only uses right and down moves, print Possible. Otherwise, print Impossible.

Sample Input 1

4 5
##...
.##..
..##.
...##

Sample Output 1

Possible

The matrix can be generated by a 7-move sequence: right, down, right, down, right, down, and right.

Sample Input 2

5 3
###
..#
###
#..
###

Sample Output 2

Impossible

Sample Input 3

4 5
##...
.###.
.###.
...##

Sample Output 3

Impossible

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using static System.Math;

namespace CompetitionPrograming2
{
    public sealed class Program : BaseProgram
    {
        public static void Main(string[] _) { using (new SetConsole()) { Solve(); } }
        public static void Solve()
        {
            var hw = GetArray<int>();
            var h = hw[0];
            var w = hw[1];
            var array = new char[h][];
            for (int i = 0; i < h; i++)
            {
                array[i] = GetString().AsEnumerable().ToArray();
            }

            Write(Bfs(array, h, w) && IsSaitan(array, h, w) ? "Possible" : "Impossible");
        }

        private static int[] dx = new int[] { 1, 0 };
        private static int[] dy = new int[] { 0, 1 };

        public static bool Bfs(char[][] map, int h, int w)
        {
            var history = new bool[h][];
            for (int i = 0; i < h; i++)
            {
                history[i] = new bool[w];
            }

            var que = new Queue<int[]>();
            que.Enqueue(new int[] { 0, 0 });
            history[0][0] = true;
            while (que.Any())
            {
                var d = que.Dequeue();
                var right = new int[] { d[0] + dy[0], d[1] + dx[0] };
                var under = new int[] { d[0] + dy[1], d[1] + dx[1] };
                if (h > right[0] && w > right[1]
                    && map[right[0]][right[1]] == '#')
                {
                    history[right[0]][right[1]] = true;
                    que.Enqueue(right);
                }

                if (h > under[0] && w > under[1]
                    && map[under[0]][under[1]] == '#')
                {
                    history[under[0]][under[1]] = true;
                    que.Enqueue(under);
                }
            }

            if (!history[h - 1][w - 1]) { return false; }

            return true;
        }

        public static bool IsSaitan(char[][] map, int h, int w)
        {
            var history = new bool[h][];
            for (int i = 0; i < h; i++)
            {
                history[i] = new bool[w];
            }

            var que = new Queue<int[]>();
            que.Enqueue(new int[] { 0, 0 });
            history[0][0] = true;

            while (que.Any())
            {
                var d = que.Dequeue();
                var right = new int[] { d[0] + dy[0], d[1] + dx[0] };
                var under = new int[] { d[0] + dy[1], d[1] + dx[1] };
                if (h > right[0] && w > right[1]
                    && map[right[0]][right[1]] == '#')
                {
                    history[right[0]][right[1]] = true;
                    que.Enqueue(right);
                    continue;
                }

                if (h > under[0] && w > under[1]
                    && map[under[0]][under[1]] == '#')
                {
                    history[under[0]][under[1]] = true;
                    que.Enqueue(under);
                }
            }

            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    if (map[i][j] == '#' && !history[i][j])
                    {
                        return false;
                    }
                }
            }

            return true;
        }
    }
    public abstract class BaseProgram
    {
        protected readonly static long divisor = 1000000007;
        protected static void Write(object obj) => Console.WriteLine(obj);
        protected static string GetString()
        {
            var str = Console.ReadLine();
            if (str == null) { throw new NullReferenceException("標準入力がnullです Solveメソッド内の解答コードが間違っています"); }
            return str;
        }
        protected static T GetNumber<T>() where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>, IFormattable
        {
            var str = GetString();
            var t = typeof(T);
            try
            {
                if ((t == typeof(byte)))
                {
                    return (T)(object)str.ToByte();
                }
                else if (t == typeof(int))
                {
                    return (T)(object)str.ToInt();
                }
                else if (t == typeof(long))
                {
                    return (T)(object)str.ToLong();
                }
                else if (t == typeof(double))
                {
                    return (T)(object)str.ToDouble();
                }
                else if (t == typeof(decimal))
                {
                    return (T)(object)str.ToDecimal();
                }
                else if (t == typeof(BigInteger))
                {
                    return (T)(object)str.ToBigInteger();
                }
            }
            catch (OverflowException)
            {
                throw new OverflowException("より大きい数値型を指定してください");
            }
            throw new NotSupportedException();
        }
        protected static T[] GetArray<T>() where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>
        {
            return GetString().ToArray<T>();
        }
        protected static List<T> GetList<T>() where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>
        {
            return GetString().ToList<T>();
        }
        protected static TResult[] GetArray<TResult>(Func<string, TResult> selector)
        {
            return (TResult[])(object)GetString().Split().Select(selector).ToArray();
        }
        protected static void Swap<T>(ref T item1, ref T item2)
        {
            var tmp = item1;
            item1 = item2;
            item2 = tmp;
        }
        protected sealed class SetConsole : IDisposable
        {
            readonly StreamWriter sw = new StreamWriter(Console.OpenStandardOutput());
            public SetConsole()
            {
                sw.AutoFlush = false;
                Console.SetOut(sw);
            }
            public void Dispose()
            {
                Console.Out.Flush();
                sw.AutoFlush = true;
                Console.SetOut(sw);
            }
        }
    }
    public static class ExtentionsLibrary
    {
        public static T[] NextPermutation<T>(this IEnumerable<T> collection) where T : IComparable
        {
            var array = collection.ToArray();
            int? exchangingNumIndex = null;
            for (int i = 1; i < array.Length; i++)
            {
                if (array[i - 1].CompareTo(array[i]) >= 0) { continue; }

                exchangingNumIndex = i - 1;
            }

            if (exchangingNumIndex == null) { return null; }

            for (int j = array.Length - 1; j >= 0; j--)
            {
                if (array[(int)exchangingNumIndex].CompareTo(array[j]) >= 0) { continue; }

                var tmp = array[j];
                array[j] = array[(int)exchangingNumIndex];
                array[(int)exchangingNumIndex] = tmp;
                array = array.Take((int)exchangingNumIndex + 1).Concat(array.Skip((int)exchangingNumIndex + 1).Reverse()).ToArray();
                break;
            }
            return array;
        }
        public static IEnumerable<T[]> Permutations<T>(this IEnumerable<T> collection) where T : IComparable
        {
            var next = collection.NextPermutation();

            while (next != null)
            {
                yield return next;

                next = next.NextPermutation();
            }
        }
        public static long Gcd(this long a, long b)
        {
            if (a < b) { return Gcd(b, a); }
            long tmp;
            do
            {
                tmp = a % b;
                a = b;
                b = tmp;
            } while (tmp != 0);
            return a;
        }
        public static IEnumerable<Tuple<long, int>> Factorize(this long n)
        {
            yield return Tuple.Create(1L, 1);
            var rootN = Math.Sqrt(n);
            for (long i = 2; i <= rootN; i++)
            {
                if (n % i != 0) { continue; }

                var count = 1;
                n /= i;
                while (n % i == 0)
                {
                    n /= i;
                    count++;
                }
                yield return Tuple.Create(i, count);
            }
            if (n != 1) { yield return Tuple.Create(n, 1); }
        }
        public static T[,] CopyArray<T>(this T[,] array)
        {
            var firstDimentionLength = array.GetLength(0);
            var secondDimentionLength = array.GetLength(1);
            var newDArray = new T[firstDimentionLength, secondDimentionLength];
            Array.Copy(array, newDArray, firstDimentionLength * secondDimentionLength);
            return newDArray;
        }
        public static T[] ToArray<T>(this string str) where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>
        {
            if (typeof(T) == typeof(string)) { return (T[])(object)str.Split(); }

            return str.ConvertEnumerator<T>().ToArray();
        }
        public static List<T> ToList<T>(this string str) where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>
        {
            if (typeof(T) == typeof(string)) { return (List<T>)(object)str.Split().ToList(); }

            return str.ConvertEnumerator<T>().ToList();
        }
        public static IEnumerable<T> ConvertEnumerator<T>(this string str) where T : IComparable, IComparable<T>, IConvertible, IEquatable<T>
        {
            var t = typeof(T);
            if (t == typeof(byte))
            {
                return (IEnumerable<T>)str.Split().Select(byte.Parse);
            }
            if (t == typeof(int))
            {
                return (IEnumerable<T>)str.Split().Select(int.Parse);
            }
            if (t == typeof(long))
            {
                return (IEnumerable<T>)str.Split().Select(long.Parse);
            }
            if (t == typeof(double))
            {
                return (IEnumerable<T>)str.Split().Select(double.Parse);
            }
            if (t == typeof(decimal))
            {
                return (IEnumerable<T>)str.Split().Select(decimal.Parse);
            }
            if (t == typeof(BigInteger))
            {
                return (IEnumerable<T>)str.Split().Select(BigInteger.Parse);
            }
            throw new NotSupportedException();
        }
        public static byte ToByte(this string str) => byte.Parse(str);
        public static byte ToByte(this char chr) => byte.Parse(chr.ToString());
        public static int ToInt(this string str) => int.Parse(str);
        public static int ToInt(this char chr) => int.Parse(chr.ToString());
        public static long ToLong(this string str) => long.Parse(str);
        public static double ToDouble(this string str) => double.Parse(str);
        public static decimal ToDecimal(this string str) => decimal.Parse(str);
        public static BigInteger ToBigInteger(this string str) => BigInteger.Parse(str);
        public static DateTime ToDateTime(this string str) => DateTime.Parse(str);
        public static string StringJoin(this object[] array, string separator = "") => string.Join(separator, array);
        public static string StringJoin<T>(this IEnumerable<T> collection, string separator = "") => string.Join(separator, collection.Select(c => c.ToString()));
        public static int LowerBound<T>(this IReadOnlyList<T> a, T v) => LowerBound(a, v, Comparer<T>.Default);
        public static int LowerBound<T>(this IReadOnlyList<T> a, T v, Comparer<T> cmp)
        {
            var l = 0;
            var r = a.Count - 1;
            while (l <= r)
            {
                var mid = l + (r - l) / 2;
                var result = cmp.Compare(a[mid], v);
                if (result == -1)
                {
                    l = mid + 1;
                }
                else
                {
                    r = mid - 1;
                }
            }
            return l;
        }
        public static int UpperBound<T>(this IReadOnlyList<T> a, T v) => UpperBound(a, v, Comparer<T>.Default);
        public static int UpperBound<T>(this IReadOnlyList<T> a, T v, Comparer<T> cmp)
        {
            var l = 0;
            var r = a.Count - 1;
            while (l <= r)
            {
                var mid = l + (r - l) / 2;
                var res = cmp.Compare(a[mid], v);
                if (res <= 0) l = mid + 1;
                else r = mid - 1;
            }
            return l;
        }
    }
    public struct Mint

    {
        public static long MOD = (long)1e9 + 7;

        /// <summary>
        /// 0以上MOD未満の整数
        /// </summary>
        public long Value;

        public Mint(long val)
        {
            Value = val % MOD;
            if (Value < 0) Value += MOD;
        }

        private static Mint Ctor(long val)
        {
            return new Mint() { Value = val };
        }

        public static Mint operator +(Mint a, Mint b)
        {
            long res = a.Value + b.Value;
            if (res > MOD) res -= MOD;
            return Ctor(res);
        }
        public static Mint operator -(Mint a, Mint b)
        {
            long res = a.Value - b.Value;
            if (res < 0) res += MOD;
            return Ctor(res);
        }

        public static Mint operator *(Mint a, Mint b)
        {
            long res = a.Value * b.Value;
            if (res > MOD) res %= MOD;
            return Ctor(res);
        }

        public static Mint operator /(Mint a, Mint b)
        {
            return a * Inv(b);
        }

        public static Mint Pow(Mint a, long n)
        {
            if (n == 0) return new Mint(1);
            Mint b = Pow(a, n >> 1);
            b *= b;
            if ((n & 1) == 1) b *= a;
            return b;
        }

        public static Mint Inv(Mint n)
        {
            long a = n.Value;
            long b = MOD;

            long x = 1;
            long u = 0;
            while (b != 0)
            {
                long k = a / b;
                long _x = u;
                u = x - k * u;
                x = _x;

                long _a = a;
                a = b;
                b = _a - (k * b);
            }

            return new Mint(x);
        }

        public override string ToString()
        {
            return Value.ToString();
        }

        public static implicit operator Mint(long a) { return new Mint(a); }
        public static explicit operator long(Mint a) { return a.Value; }
        public static Mint Choose(long n, long k)
        {
            Mint numerator = 1, denominator = 1;
            for (int i = 0; i < k; i++)
            {
                numerator *= n - i;
                denominator *= i + 1;
            }
            return numerator / denominator;
        }
    }
    public sealed class Settings
    {
        public enum Priority : byte
        {
            Smaller = 0,
            Larger = 1
        }
    }
}