use std::str::FromStr;
use std::io::*;
use utils::*;
use std::cmp::*;
use std::iter::FromIterator;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = AtRead::from(i);
    let ab = i.read2::<usize, usize>();
    let result = solve(ab);
    writeln!(o, "{} {}", result.len(), result[0].len()).unwrap();
    for row in &result {
        let s = String::from_iter(row.iter().map(|&x| if x { '.' } else { '#' }));
        writeln!(o, "{}", s).unwrap();
    }
}
fn solve(ab: (usize, usize)) -> Vec<Vec<bool>> {
    let w = 100;
    let h = 90;
    let mut r = vec![vec![false; w]; h];
    for y in h / 2..h {
        for x in 0..w {
            r[y][x] = true;
        }
    }
    let mut a = ab.0 - 1;
    let mut y = 0;
    while a != 0 {
        let c = min(a, w / 2);
        for i in 0..c {
            r[y][i * 2] = true;
        }
        a -= c;
        y += 2;
    }

    let mut b = ab.1 - 1;
    let mut y = h - 1;
    while b != 0 {
        let c = min(b, w / 2);
        for i in 0..c {
            r[y][i * 2] = false;
        }
        b -= c;
        y -= 2;
    }
    r
}

fn verify(r: Vec<Vec<bool>>) -> (usize, usize) {
    let h = r.len();
    let w = r[0].len();

    let mut r_ex = vec![vec![None; w + 2]; h + 2];
    for y in 0..h {
        for x in 0..w {
            r_ex[y + 1][x + 1] = Some(r[y][x]);
        }
    }

    let mut used = vec![vec![false; w]; h];
    let mut q = Vec::new();
    let mut a = 0;
    let mut b = 0;
    for y in 0..h {
        for x in 0..w {
            if used[y][x] {
                continue;
            }
            let r = r[y][x];
            q.push((y + 1, x + 1));
            while let Some((y, x)) = q.pop() {
                if r_ex[y][x] != Some(r) || used[y - 1][x - 1] {
                    continue;
                }
                used[y - 1][x - 1] = true;
                q.push((y - 1, x));
                q.push((y + 1, x));
                q.push((y, x - 1));
                q.push((y, x + 1));
            }
            if r {
                a += 1;
            } else {
                b += 1;
            }
        }
    }
    (a, b)
}

mod utils {
    use super::*;

    pub struct AtRead<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        {$f:ident($($v:ident: $t:ident),*)} => {
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                $(
                    let $v = next(i);
                )*
                ($($v),*)
            }
        };
    }

    impl<R: BufRead> AtRead<R> {
        pub fn from(r: R) -> Self {
            AtRead {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        fn_read! { read2(v1: T1, v2: T2) }
    }

    fn next<'a, T: FromStr, I: std::iter::Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

}


Measured memory_bytes: 4352