Problem:
Score : 400 points

Problem Statement

We have an H-by-W matrix.
Let a_{ij} be the element at the i-th row from the top and j-th column from the left.
In this matrix, each a_{ij} is a lowercase English letter.

Snuke is creating another H-by-W matrix, A', by freely rearranging the elements in A.
Here, he wants to satisfy the following condition:

Every row and column in A' can be read as a palindrome.

Determine whether he can create a matrix satisfying the condition.

Note

A palindrome is a string that reads the same forward and backward.
For example, a, aa, abba and abcba are all palindromes, while ab, abab and abcda are not.

Constraints

1 ≤ H, W ≤ 100

a_{ij} is a lowercase English letter.

Input

Input is given from Standard Input in the following format:

H W
a_{11}a_{12}...a_{1W}
:
a_{H1}a_{H2}...a_{HW}

Output

If Snuke can create a matrix satisfying the condition, print Yes; otherwise, print No.

Sample Input 1

3 4
aabb
aabb
aacc

Sample Output 1

Yes

For example, the following matrix satisfies the condition.

abba
acca
abba

Sample Input 2

2 2
aa
bb

Sample Output 2

No

It is not possible to create a matrix satisfying the condition, no matter how we rearrange the elements in A.

Sample Input 3

5 1
t
w
e
e
t

Sample Output 3

Yes

For example, the following matrix satisfies the condition.

t
e
w
e
t

Sample Input 4

2 5
abxba
abyba

Sample Output 4

No

Sample Input 5

1 1
z

Sample Output 5

Yes

Solution in Rust (1.42.0) (judge verdict: Wrong Answer)

#![allow(unused_imports)]

// language: Rust(1.42.0)
// check available crates on AtCoder at "https://atcoder.jp/contests/language-test-202001"
// My Library Repositry is at "https://github.com/Loptall/prcn_lib"

/*
    青perfほしいよ〜！
*/

// from std...
use std::cmp::{
    max, min, Ordering,
    Ordering::{Equal, Greater, Less},
    Reverse,
};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::convert::TryInto;
use std::fmt;
use std::mem::swap;
use std::num::{NonZeroU32, ParseIntError};
use std::ops::{
    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
    Index, IndexMut, Mul, MulAssign, Neg, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
    SubAssign,
};
use std::process::exit;
use std::{f32, f64, i128, i16, i32, i64, i8, isize, u128, u16, u32, u64, u8, usize};

// Dep' crates are...
use itertools::*;
use itertools_num::*;
use lazy_static::lazy_static;
use maplit::{btreemap, btreeset, hashmap, hashset};
use num_bigint::{BigInt, BigUint};
use num_complex::Complex;
use num_integer::{binomial, gcd, lcm, multinomial, Integer};
use num_rational::Rational;
use num_traits::{
    clamp, one, pow, zero, Num, NumAssignOps, NumOps, One, Pow, Signed, Unsigned, Zero,
};
use permutohedron::Heap;
use proconio::{
    derive_readable, fastout, input, is_stdin_empty,
    marker::{Bytes, Chars, Isize1, Usize1},
};
use rand::random;

pub trait Visualize {
    fn visualize(&self, split: &str);
    fn continuous(&self) {
        self.visualize("");
    }
    fn spaces(&self) {
        self.visualize(" ");
    }
    fn lines(&self) {
        self.visualize("\n");
    }
}
macro_rules ! impl_vis_for_sized {($ ($ t : ty ) ,+ ) => {$ (impl Visualize for $ t {fn visualize (& self , _split : & str ) {print ! ("{}" , self ) ; } } ) + } ; }
impl_vis_for_sized! {usize , u8 , u16 , u32 , u64 , u128 , isize , i8 , i16 , i32 , i64 , i128 , String , & str }
impl<T: fmt::Display> Visualize for [T] {
    fn visualize(&self, split: &str) {
        print!("{}", self.iter().join(split));
    }
}
/// macro to output answer improved to println
///
/// this macro will print '\n' at the last.
///
/// # Patterns
///
/// `,`, it means one space, it formats the elements, which is before, space-split.
/// And insert a space after the prefix, unless it is at last.
///
/// `=>`, it means empty string, it formats the element, witch is before, without any split.
/// And insert nothing between two element.
///
/// `;`, it means newline(\n), it formats the element, witch is before, newline-split.
/// And insert a newline after the prefix, unless it is at last.
///
/// # Eample
///
/// ```
/// #[test]
/// fn vis_test() {
///     let a = 1;
///     let b = 2;
///     let c = 3;
///
///     let v = vec!['a', 'b', 'c'];
///
///     // single element test ...
///
///     vis!(a); // 1\n
///     vis!(a,); // 1\n
///     vis!(a =>); // 1\n
///     vis!(a;); // 1\n
///
///     println!();
///
///     vis!(a + b); // 3\n
///
///     println!();
///
///     vis!(v); // a b c\n
///     vis!(v,); // a b c\n
///     vis!(v =>); // abc\n
///     vis!(v;); // a\nb\nc\n
///
///     println!();
///
///     // multi elements connected by common operater test ...
///
///     println!();
///
///     vis!(a, b); // 1 2\n
///     vis!(a, b, c); // 1 2 3\n
///     vis!(a, b, c;); // 1 2 3\n
///
///     println!();
///
///     vis!(a => b); // 12\n
///     vis!(a => b => c); // 123\n
///     vis!(a => b => c ,); // 123\n
///
///     println!();
///
///     vis!(a; b); // 1\n2\n
///     vis!(a; b; c); // 1\n2\n3\n
///     vis!(a; b; c =>); // 1\n2\n3\n
///
///     println!();
///
///     // multi elements connected by different operater test ...
///
///     vis!(a, b; c); // 1 2\n3\n
///     vis!(a; b, c); // 1\n2 3\n
///     vis!(a => b, c); // 12 3\n
///     vis!(a; b => c); // 1\n23\n
///
///     println!();
///
///     vis!(a, v); // 1 a b c\n;
///     vis!(a, v;); // 1 a\nb\nc\n;
///     vis!(a => v =>); // 1abc\n;
///
///     println!("\d");
///     // panic!()
/// }
/// ```
#[macro_export]
macro_rules ! vis {() => {println ! () ; } ; ($ last : expr ; ) => {$ last . lines () ; vis ! () } ; ($ last : expr => ) => {$ last . continuous () ; vis ! () ; } ; ($ last : expr $ (, ) ? ) => {$ last . spaces () ; vis ! () ; } ; ($ first : expr ; $ ($ rest : tt ) * ) => {$ first . lines () ; println ! () ; vis ! ($ ($ rest ) * ) ; } ; ($ first : expr => $ ($ rest : tt ) * ) => {$ first . continuous () ; vis ! ($ ($ rest ) * ) ; } ; ($ first : expr , $ ($ rest : tt ) * ) => {$ first . spaces () ; print ! (" " ) ; vis ! ($ ($ rest ) * ) ; } ; }

pub const MOD10E9_7: usize = 1000000007;
pub const MOD99_: usize = 998244353;
pub const MAX: usize = std::usize::MAX;
pub const PI: f64 = f64::consts::PI;
pub const ASCII_A: u8 = 65;
pub const ASCII_0: u8 = 48;

// code...
// #[fastout]
fn main() {
    input! {
        h: usize, w: usize,
        a: [Chars; h]
    }

    let mut c = vec![0; 26];
    for i in a.iter().flatten() {
        c[((*i as u8) - ('a' as u8)) as usize] += 1;
    }

    c.sort();
    c.reverse();

    dbg!(&c);

    let g = if h.is_odd() && w.is_odd() {
        (1, (h + w - 1) / 2, (h - 1) * (w - 1) / 4)
    } else if h.is_even() && w.is_even() {
        (0, 0, h * w / 4)
    } else {
        (0, if h.is_even() { h } else { w } / 2, (h / 2) * (w / 2))
    };

    dbg!(g);

    for _ in 0..g.0 {
        if let Some(e) = c.iter_mut().find(|x| **x % 4 == 1 || **x % 4 == 3) {
            *e -= 1;
        }
    }
    for _ in 0..g.1 {
        if let Some(e) = c.iter_mut().find(|x| **x % 4 == 2) {
            *e -= 2;
        }
    }
    for _ in 0..g.2 {
        if let Some(e) = c.iter_mut().find(|x| **x % 4 == 0 && **x > 0) {
            *e -= 4;
        }
    }

    dbg!(&c);

    if c.iter().all(|x| *x == 0) {
        vis!("Yes");
    } else {
        vis!("No");
    }
}