#[allow(unused_macros)]
macro_rules! my_write {
  ($writer:expr, $arg:expr) => {
    $writer.write($arg).unwrap()
  };
  ($writer:expr, $arg:expr,) => {
    my_write!($writer, $arg)
  };
  ($writer:expr, $($arg:expr),+ $(,)?) => {
    {
      let mut buf = Vec::new();
      $(buf.write($arg).unwrap();)+
      $writer.write(&buf).unwrap()
    }
  };
}

use std::io::{ stdin, stdout, Write };

#[inline(always)]
fn find_bit<F>(n: usize, mut func: F)
  where F: FnMut(usize)
{
  let mut tmp = n;
  let mut x   = tmp & (!tmp).wrapping_add(1);
  while x != 0 {
    func(x);
    tmp ^= x;
    x = tmp & (!tmp).wrapping_add(1);
  }
}

#[inline(always)]
fn abc173_c() {
  let stdin  = stdin();
  let stdout = stdout();
  let mut scanner = my::Scanner::with_capacity(12, stdin.lock());
  let mut writer  = stdout.lock();
  let mut itoa    = my::ItoA::with_capacity(10);

  let h = my::atoi::<usize>(scanner.read_until(my::SP));
  let w = my::atoi::<usize>(scanner.read_until(my::SP));
  let k = my::atoi::<usize>(scanner.read_until(my::LF));

  let orig = scanner.fold(h, my::LF, Vec::with_capacity(h), | mut v, s | {
    let mut n = 0;
    for i in 0..w {
      n |= if s[i] == b'.' { 0 } else { 1 } << ((w - 1) - i);
    }
    v.push(n);
    v
  });

  let mut ans = 0;
  let row = 1 << h;
  let col = 1 << w;

  let mut map = rustc_hash::FxHashMap::default();
  for i in 0..std::cmp::max(h, w) {
    map.insert(1 << i, i);
  }

  let mut vec = Vec::with_capacity(h);
  vec.resize(h, 0);
  for i in 0..orig.len() {
    vec[i] = orig[i];
  }

  for i in 0..row {
    for j in 0..col {
      for k in 0..orig.len() {
        vec[k] = orig[k];
      }
      find_bit(i, | x | { vec[map[&x]] = 0 });

      let mut mask = 0;
      find_bit(j, | x | { mask |= 1 << map[&x] });

      let mut cnt = 0;
      for k in 0..vec.len() {
        vec[k] &= !mask;
        find_bit(vec[k], | _ | { cnt += 1 });
      }

      if cnt == k {
        ans += 1;
      }
    }
  }

  my_write!(writer, itoa.from_usize(ans), b"\n");
  writer.flush().unwrap();
}

fn main() {
  abc173_c();
}

//------------------------------------------------------------------------
mod my {
  use std::ops::{ Add, Sub, Mul };

  #[allow(dead_code)]
  pub const SP: u8 = b' ';
  #[allow(dead_code)]
  pub const LF: u8 = b'\n';

  //----------------------------------------------------------------------
  #[allow(dead_code)]
  pub fn atoi<T>(s: &[u8]) -> T
    where T: Add<Output=T> +
             Sub<Output=T> +
             Mul<Output=T> +
             Default +
             From<u8> +
             ::std::fmt::Debug
  {
    let n = T::default();

    if s.is_empty() {
      return n;
    }

    match s[0] {
      b'+' => s[1..].iter().fold(n, | acc, x | { (acc * T::from(10)) + T::from(x - b'0') }),
      b'-' => s[1..].iter().fold(n, | acc, x | { (acc * T::from(10)) - T::from(x - b'0') }),
      _    => s[0..].iter().fold(n, | acc, x | { (acc * T::from(10)) + T::from(x - b'0') }),
    }
  }

  //----------------------------------------------------------------------
  macro_rules! pub_fn_ItoA_from_ty {
    ($($name:ident => $_type:ty),+ $(,)?) => {$(
      #[allow(dead_code)]
      #[allow(unused_comparisons)]
      #[inline(always)]
      pub fn $name(&mut self, mut n: $_type) -> &[u8] {
        self.buf.clear();
        if n == 0 {
          self.buf.push(b'0');
          return self.buf.as_slice();
        }

        let mut is_negative = false;
        if n < 0 {
          is_negative = true;
          n = (!n).wrapping_add(1);
        }

        while n > 0 {
          self.buf.push((n % 10) as u8 + b'0');
          n /= 10;
        }
        if is_negative {
          self.buf.push(b'-');
        }
        self.buf.reverse();
        self.buf.as_slice()
      }
    )+};
  }

  #[derive(Debug)]
  pub struct ItoA {
    buf: Vec<u8>,
  }

  impl ItoA {
    #[allow(dead_code)]
    #[inline(always)]
    pub fn with_capacity(cap: usize) -> Self {
      ItoA {
        buf: Vec::with_capacity(cap),
      }
    }

    pub_fn_ItoA_from_ty!(
      from_usize => usize,
      from_u8    => u8,
      from_u16   => u16,
      from_u32   => u32,
      from_u64   => u64,
      from_u128  => u128,
      from_isize => isize,
      from_i8    => i8,
      from_i16   => i16,
      from_i32   => i32,
      from_i64   => i64,
      from_i128  => i128,
    );
  } // impl ItoA

  //----------------------------------------------------------------------
  #[derive(Debug)]
  pub struct Scanner<R> {
    reader: R,
    buf   : Vec<u8>,
  }

  impl<R> Scanner<R>
    where R: ::std::io::BufRead
  {
    #[allow(dead_code)]
    #[inline(always)]
    pub fn with_capacity(cap: usize, reader: R) -> Self {
      Scanner {
        reader: reader,
        buf   : Vec::with_capacity(cap),
      }
    }

    #[allow(dead_code)]
    #[inline(always)]
    pub fn read_until(&mut self, delim: u8) -> &[u8] {
      self.buf.clear();
      let mut len = self.reader.read_until(delim, &mut self.buf).unwrap();
      if len == 0 {
        return self.buf.as_slice();
      }

      len -= 1;
      if self.buf[len] == delim {
        self.buf.truncate(len);
      }
      self.buf.as_slice()
    }

    #[allow(dead_code)]
    #[inline(always)]
    pub fn for_each<F>(&mut self, n: usize, delim: u8, mut func: F)
      where F: FnMut(&[u8])
    {
      for _ in 0..n - 1 {
        func(self.read_until(delim));
      }
      func(self.read_until(LF))
    }

    #[allow(dead_code)]
    #[inline(always)]
    pub fn fold<B, F>(&mut self, n: usize, delim: u8, mut init: B, mut func: F) -> B
      where F: FnMut(B, &[u8]) -> B
    {
      for _ in 0..n - 1 {
        init = func(init, self.read_until(delim));
      }
      func(init, self.read_until(LF))
    }
  } // impl<R> Scanner<R>

} // mod my


Measured memory_bytes: 2164