#[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,
  BufRead,
  StdoutLock
};

use std::ops::{
  Not,
  BitAnd,
  BitXor
};

use num_traits::{
  identities::{
    Zero,
    One
  },
  ops::wrapping::WrappingAdd
};

#[inline(always)]
fn fold_bitflag<T, U, F>(mut n: T, mut init: U, mut func: F) -> U
  where F: FnMut(U, T) -> U,
        T: Copy +
           PartialEq +
           Not<Output=T> +
           BitAnd<Output=T> +
           BitXor<Output=T> +
           Zero +
           One +
           WrappingAdd
{
  loop {
    let flg = n & (!n).wrapping_add(&T::one());
    if flg == T::zero() {
      break init;
    }
    init = func(init, flg);
    n = n ^ flg;
  }
}

#[inline(always)]
fn abc173_c<R>(
  mut scanner: my::Scanner<R>,
  mut writer : StdoutLock,
  #[allow(unused_variables, unused_mut)]
  mut itoa   : my::ItoA
)
  where R: BufRead
{
  let h = my::atoi::<usize>(scanner.read_until(my::SP));
  let w = my::atoi::<usize>(scanner.read_until(my::SP));
  let k = my::atoi::<u32>(scanner.read_until(my::LF));

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

  let mut ans = 0;

  for row in 0..1 << h {
    for col in 0..1 << w {
      let cnt = fold_bitflag(row, 0, | acc, x: u8 | {
        let i = x.trailing_zeros() as usize;
        acc + (vec[i] & col).count_ones()
      });

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

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

fn main() {
  let stdin  = stdin();
  let stdout = stdout();

  abc173_c(
    my::Scanner::with_capacity(12, stdin.lock()),
    stdout.lock(),
    my::ItoA::with_capacity(10));
}

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

  use num_traits::{
    cast::NumCast,
    ops::wrapping::WrappingAdd,
    identities::{
      Zero,
      One
    }
  };

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

  macro_rules! num_cast {
    ($v0:expr)          => { num_traits::cast::cast::<_, _>($v0).unwrap() };
    ($v0:expr, $ret:ty) => { num_traits::cast::cast::<_, $ret>($v0).unwrap() };
  }

  //----------------------------------------------------------------------
  #[inline(always)]
  fn atoi0<T, F>(s: &[u8], n: T, func: F) -> T
    where F: Fn(T, T) -> T,
          T: Mul<Output=T> +
             NumCast
  {
    s.iter().fold(n, | acc, b | {
      func(acc * num_cast!(10), num_cast!(b - b'0'))
    })
  }

  #[allow(dead_code)]
  #[inline(always)]
  pub fn atoi<T>(s: &[u8]) -> T
    where T: Add<Output=T> +
             Sub<Output=T> +
             Mul<Output=T> +
             NumCast +
             Zero
  {
    let n = T::zero();

    if s.is_empty() {
      return n;
    }

    match s[0] {
      b'+' => atoi0(&s[1..], n, T::add),
      b'-' => atoi0(&s[1..], n, T::sub),
      _    => atoi0(&s[0..], n, T::add),
    }
  }

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

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

    #[allow(dead_code)]
    #[inline(always)]
    pub fn from<T>(&mut self, mut n: T) -> &[u8]
      where T: Copy +
               PartialEq +
               PartialOrd +
               Div<Output=T> +
               Rem<Output=T> +
               Not<Output=T> +
               NumCast +
               Zero +
               One +
               WrappingAdd
    {
      let zero = T::zero();
      let one  = T::one();
      let ten  = num_cast!(10);

      self.buf.clear();
      if n == zero {
        self.buf.push(b'0');
        return self.buf.as_slice();
      }

      let mut is_negative = false;
      if n < zero {
        is_negative = true;
        n = (!n).wrapping_add(&one);
      }

      while n > zero {
        self.buf.push(num_cast!(n % ten, u8) + b'0');
        n = n / ten;
      }
      if is_negative {
        self.buf.push(b'-');
      }
      self.buf.reverse();
      self.buf.as_slice()
    }
  } // 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(capa: usize, reader: R) -> Self {
      Self {
        reader: reader,
        buf   : Vec::with_capacity(capa),
      }
    }

    #[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<T, F>(&mut self, n: usize, delim: u8, mut init: T, mut func: F) -> T
      where F: FnMut(T, &[u8]) -> T
    {
      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: 2172