Problem:
Score : 300 points

Problem Statement

We have a grid of H rows and W columns of squares. The color of the square at the i-th row from the top and the j-th column from the left (1 \leq i \leq H, 1 \leq j \leq W) is given to you as a character c_{i,j}: the square is white if c_{i,j} is ., and black if c_{i,j} is #.

Consider doing the following operation:

Choose some number of rows (possibly zero), and some number of columns (possibly zero). Then, paint red all squares in the chosen rows and all squares in the chosen columns.

You are given a positive integer K. How many choices of rows and columns result in exactly K black squares remaining after the operation? Here, we consider two choices different when there is a row or column chosen in only one of those choices.

Constraints

1 \leq H, W \leq 6

1 \leq K \leq HW

c_{i,j} is . or #.

Input

Input is given from Standard Input in the following format:

H W K
c_{1,1}c_{1,2}...c_{1,W}
c_{2,1}c_{2,2}...c_{2,W}
:
c_{H,1}c_{H,2}...c_{H,W}

Output

Print an integer representing the number of choices of rows and columns satisfying the condition.

Sample Input 1

2 3 2
..#
###

Sample Output 1

5

Five choices below satisfy the condition.

The 1-st row and 1-st column

The 1-st row and 2-nd column

The 1-st row and 3-rd column

The 1-st and 2-nd column

The 3-rd column

Sample Input 2

2 3 4
..#
###

Sample Output 2

1

One choice, which is choosing nothing, satisfies the condition.

Sample Input 3

2 2 3
##
##

Sample Output 3

0

Sample Input 4

6 6 8
..##..
.#..#.
#....#
######
#....#
#....#

Sample Output 4

208

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace ABC173
{
    using static Ex;
    public class Solve
    {
        public static void Main(string[] args)
        {
            new ABC_C();
        }
    }
    public class ABC_A
    {
        public ABC_A()
        {
            var n = ReadInt;
            if ((n % 1000) == 0)
            {
                0.Cw();
                return;
            }
            (1000 - (n % 1000)).Cw();
        }
    }
    public class ABC_B
    {
        public ABC_B()
        {
            var n = ReadInt;
            var dict = new Dictionary<string, long>();
            dict["AC"] = 0;
            dict["WA"] = 0;
            dict["TLE"] = 0;
            dict["RE"] = 0;
            for (int i = 0; i < n; i++)
            {
                var s = Read;
                dict[s]++;
            }
            foreach (var v in dict)
            {
                $"{v.Key} x {v.Value}".Cw();
            }
        }
    }
    public class ABC_C
    {
        /// <summary>
        /// H 行 W 列
        /// 上から i 行目、左から j 列目 ( 1 ≤ i ≤ H , 1 ≤ j ≤ W ) のマスの色は文字 c i , j
        /// c i , j が . のとき白
        /// # のとき黒
        /// </summary>
        int h, w, k;
        long ans;
        bool[][] arr;
        bool[] redh, redw;
        public ABC_C()
        {
            (h, w, k) = ReadIntArray().ToTpl3();

            arr = new bool[h][];
            //var ch = new long[h];
            //var cw = new long[w];

            for (int i = 0; i < h; i++)
            {
                var s = Read;
                arr[i] = s.Select(v => v == '#').ToArray();
                //ch[i] = arr[i].Count(v => v);
                //all += ch[i];

                //for (int j = 0; j < w; j++)
                //{
                //    if (arr[i][j]) cw[j]++;
                //}
            }

            for (int bit = 0; bit < 1 << h; bit++)
            {
                redh = new bool[h];
                for (int i = 0; i < h; i++)
                {
                    if ((bit >> i & 1) == 1)
                    {
                        redh[i] = true;
                    }
                }

                for (int s = 0; s < 1 << w; s++)
                {
                    redw = new bool[w];
                    for (int i = 0; i < w; i++)
                    {
                        if ((s >> i & 1) == 1)
                        {
                            redw[i] = true;
                        }
                    }
                    var t = Check();
                    //$"{string.Format("{0:00}", int.Parse(Convert.ToString((bit), 2)))} {string.Format("{0:000}", int.Parse(Convert.ToString((s), 2)))} {t}".Cw();
                    if (t) ans++;
                }
            }
            ans.Cw();
        }

        bool Check()
        {
            long cou = 0;
            for (int i = 0; i < h; i++)
            {
                for (int j = 0; j < w; j++)
                {
                    //$"{i} {j} {(arr[i][j] && !redh[i] && !redw[j])} {arr[i][j] } {redh[i]} {redw[j]}".Cw();
                    if (arr[i][j] && (!redh[i]) && (!redw[j])) cou++;
                    if (cou > k) return false;
                }
            }
            return (cou == k);
        }
    }

    public static class Ex
    {
        public static void Cw(this object s) { Console.WriteLine(s); }



        public static bool Mins<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) > 0) { a = b; return true; } return false; }
        public static bool Maxs<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
        public static void Swap<T>(ref T a, ref T b) { var t = b; b = a; a = t; }
        public static void Swap<T>(List<T> list, int i, int j) { T tmp = list[j]; list[j] = list[i]; list[i] = tmp; }

        public static long Lcm(int x, int y) { return x / Gcd(x, y) * y; }
        public static long Gcd(long m, long n) { if (n == 0) return m; return Gcd(n, m % n); }
        public static List<string> FastSort(this List<string> s) { s.Sort(StringComparer.Ordinal); return s.ToList(); }
        public static void yesno(this bool b) { (b ? "yes" : "no").Cw(); }
        public static void YesNo(this bool b) { (b ? "Yes" : "No").Cw(); }
        public static void YESNO(this bool b) { (b ? "YES" : "NO").Cw(); }

        public static string Read { get { return Console.ReadLine().Trim(); } }
        public static int ReadInt { get { return int.Parse(Read); } }
        public static long ReadLong { get { return long.Parse(Read); } }
        public static double ReadDouble { get { return double.Parse(Read); } }
        public static string[] ReadArray() { return Read.Split(' '); }
        public static int[] ReadIntArray() { return Read.Split(' ').Select(int.Parse).ToArray(); }
        public static long[] ReadLongArray() { return Read.Split(' ').Select(long.Parse).ToArray(); }
        public static string[] ReadArray(long N) { var v = new string[N]; for (long i = 0; i < N; ++i) v[i] = Read; return v; }
        public static int[] ReadIntArray(long N) { var v = new int[N]; for (long i = 0; i < N; ++i) v[i] = ReadInt; return v; }
        public static long[] ReadLongArray(long N) { var v = new long[N]; for (long i = 0; i < N; ++i) v[i] = ReadLong; return v; }

        public static (T, T) ToTpl2<T>(this T[] v) { return (v[0], v[1]); }
        public static (T, T, T) ToTpl3<T>(this T[] v) { return (v[0], v[1], v[2]); }
        public static (T, T, T, T) ToTpl4<T>(this T[] v) { return (v[0], v[1], v[2], v[3]); }
        public static (T, T, T, T, T) ToTpl5<T>(this T[] v) { return (v[0], v[1], v[2], v[3], v[4]); }


        public static int LowerBound<T>(T[] a, T v)
        {
            return LowerBound(a, v, Comparer<T>.Default);
        }

        public static int LowerBound<T>(T[] a, T v, Comparer<T> cmp)
        {
            var l = 0;
            var r = a.Length - 1;
            while (l <= r)
            {
                var mid = l + (r - l) / 2;
                var res = cmp.Compare(a[mid], v);
                if (res == -1) l = mid + 1;
                else r = mid - 1;
            }
            return l;
        }

        /// <summary>
        /// lower_boundは、探索したいkey以上のイテレータを返す
        /// upper_boundは、探索したいkeyより大きいイテレータを返す
        public static int UpperBound<T>(T[] a, T v)
        {
            return UpperBound(a, v, Comparer<T>.Default);
        }

        public static int UpperBound<T>(T[] a, T v, Comparer<T> cmp)
        {
            var l = 0;
            var r = a.Length - 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;
        }
    }
}