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 C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using static Input;

public class Prog
{
    private const int INF = 1000000007;
    public struct Pair { public int x, y; public Pair(int x, int y) { this.x = x; this.y = y; } }
    public static void Solve()
    {
        int H = NextInt();
        int W = NextInt();
        Dictionary<char, int> d = new Dictionary<char, int>();
        for (int i = 0; i < H; i++)
        {
            foreach (var c in NextString())
            {
                if (!d.ContainsKey(c)) d[c] = 0;
                d[c]++;
            }
        }
        if (H % 2 == 0 && W % 2 == 0)
        {
            //必ず上下左右の回文に使われるので4つないといけない
            Console.WriteLine(d.All(v => v.Value % 4 == 0) ? "Yes" : "No");
        }
        else if (H % 2 == 1 && W % 2 == 1)
        {
            //中心が1つ、中心を通る文字は2個あってもよい
            //(H-1)/2個+(W-1)/2個までok
            if (d.Count(v => v.Value % 2 == 1) > 1)
            {
                Console.WriteLine("No");
                return;
            }
            int two_c = 0;
            foreach (var e in d)
                if (e.Value % 4 != 0 && e.Value % 2 == 0) two_c++;
            Console.WriteLine(two_c <= (H + W) / 2 - 1 ? "Yes" : "No");
        }
        else
        {
            //奇数列の中央は横回文1度しか使わないため2個でもよい
            //2個が許されるのは偶数/2個まで
            if (d.Count(v => v.Value % 2 == 1) > 1)
            {
                Console.WriteLine("No");
                return;
            }
            int two_c = 0;
            foreach (var e in d)
                if (e.Value % 4 != 0 && e.Value % 2 == 0) two_c++;
            if (H % 2 == 0)
            {
                int tmp = H;
                H = W;
                W = tmp;
            }
            Console.WriteLine(two_c <= (W / 2) ? "Yes" : "No");
        }
    }
    public static void Main()
    {
        var sw = new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
        Console.SetOut(sw);
        Solve();
        Console.Out.Flush();
    }
}

public class Input
{
    private static Queue<string> q = new Queue<string>();
    private static void Confirm() { if (q.Count == 0) foreach (var s in Console.ReadLine().Split(' ')) q.Enqueue(s); }
    public static int NextInt() { Confirm(); return int.Parse(q.Dequeue()); }
    public static long NextLong() { Confirm(); return long.Parse(q.Dequeue()); }
    public static char NextChar() { Confirm(); return char.Parse(q.Dequeue()); }
    public static string NextString() { Confirm(); return q.Dequeue(); }
    public static double NextDouble() { Confirm(); return double.Parse(q.Dequeue()); }
    public static int[] LineInt() { return Console.ReadLine().Split(' ').Select(int.Parse).ToArray(); }
    public static long[] LineLong() { return Console.ReadLine().Split(' ').Select(long.Parse).ToArray(); }
    public static string[] LineString() { return Console.ReadLine().Split(' ').ToArray(); }
    public static double[] LineDouble() { return Console.ReadLine().Split(' ').Select(double.Parse).ToArray(); }
}