#[allow(unused_imports)]
use proconio::input;
#[allow(unused_imports)]
use proconio::marker::Chars;
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused)]
const ALPHA_SMALL: [char; 26] = [
    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
    't', 'u', 'v', 'w', 'x', 'y', 'z',
];
#[allow(unused)]
const ALPHA: [char; 26] = [
    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
    'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];
fn main() {
    input!(h: usize, w: usize, k: usize);
    let mut grid = vec![];
    for _ in 0..h {
        input!(c: Chars);
        grid.push(c);
    }

    let bits1 = BitSet::empty(h);
    let bits2 = BitSet::empty(w);
    let mut ans = 0;
    for b1 in bits1 {
        for b2 in bits2 {
            if check(&grid, k, b1, b2) {
                ans += 1;
            }
        }
    }

    println!("{}", ans);
}

fn check(grid: &Vec<Vec<char>>, k: usize, bits1: BitSet, bits2: BitSet) -> bool {
    let h = grid.len();
    let w = grid[0].len();
    let v1 = bits1.to_vec();
    let v2 = bits2.to_vec();
    let mut count = 0;
    for i in 0..h {
        for j in 0..w {
            if grid[i][j] == '#' && v1[i] == 0 && v2[j] == 0 {
                count += 1;
            }
        }
    }

    k == count
}

#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
struct BitSet {
    bits: usize,
    size: usize,
}

impl std::fmt::Debug for BitSet {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "BitSet {{ bits: {:b}, size: {} }}", self.bits, self.size)
    }
}

impl BitSet {
    //
    fn empty(size: usize) -> BitSet {
        if size > 64 {
            panic!("large set size")
        }
        BitSet {
            bits: 0,
            size: size,
        }
    }
    // コンンストラクター
    fn new(n: usize, size: usize) -> BitSet {
        BitSet {
            bits: n,
            size: size,
        }
    }

    // 和集合を求める
    fn union(&self, other: BitSet) -> BitSet {
        BitSet {
            bits: self.bits | other.bits,
            size: self.size, // debug
        }
    }

    // 共通部分を求める
    fn intersect(&self, other: BitSet) -> BitSet {
        BitSet {
            bits: self.bits & other.bits,
            size: self.size, // debug
        }
    }

    // n を含むかどうか
    // n = 0, bits = 0b0001 => true
    // n = 1, bits = 0b0001 => false
    fn include(&self, n: usize) -> bool {
        if self.size < n {
            return false;
        }
        self.bits & (1 << n) != 0
    }

    // bitsをvectorに変換
    // 反転することに注意！
    // 0b0001 => vec![1, 0, 0, 0]
    // 0b1010 => vec![0, 1, 0, 1]
    fn to_vec(&self) -> std::vec::Vec<usize> {
        let mut res = std::vec::Vec::new();
        let mut bits = self.bits;

        for _ in 0..self.size {
            res.push(bits % 2);
            bits /= 2;
        }
        res
    }

    // 集合を表すusizeの値を返す
    fn unwrap(&self) -> usize {
        self.bits
    }
}

impl Iterator for BitSet {
    type Item = BitSet;

    fn next(&mut self) -> Option<Self::Item> {
        if (1 << self.size) <= self.bits {
            return None;
        }
        self.bits += 1;
        Some(BitSet {
            bits: self.bits - 1,
            size: self.size,
        })
    }
}


Measured memory_bytes: 2280