#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cfloat>
#include <cstring>
#include <cctype>
#include <queue>
using namespace std;


int h, w;
char field[52][52];
int tbl[52][52];
vector<int> ps;
vector<char> cs;
int dp[522][522];

bool reachable(){
	bool visit[52][52] = {};
	queue<int> q;
	q.push(1 << 8 | 1);
	while( !q.empty() ){
		int y = q.front() >> 8;
		int x = q.front() & 255;
		q.pop();
		if(y == h && x == w) return true;

		if( field[y + 1][x] != '#' ){
			if( !visit[y+1][x] ){
				visit[y+1][x] = true;
				q.push(y + 1 << 8 | x);
			}
		}
		if( field[y][x + 1] != '#' ){
			if( !visit[y][x+1] ){
				visit[y][x+1] = true;
				q.push(y << 8 | x + 1);
			}
		}
	}
	return false;
}

void add_edge(int p, vector<int> &e){
	bool visit[52][52] = {};
	queue<int> q;
	q.push(p);

	while( !q.empty() ){
		p = q.front();
		q.pop();

		int y = p >> 8;
		int x = p & 255;
		
		for(int i = 0; i < 2; ++i){
			int ny = y + i;
			int nx = x + (1 - i);

			if( !visit[ny][nx] ){
				visit[ny][nx] = true;
				if( tbl[ny][nx] != -1 ){
					if( tbl[ny][nx] == -2 ){
						q.push(ny << 8 | nx);
					}
					else{
						e.push_back(tbl[ny][nx]);
					}
				}
			}
		}
	}
}


int main(){
	vector<int>::iterator it1, it2;

	while( scanf("%d%d", &h, &w), h != 0 ){
		memset(field, '#', sizeof field);
		memset(tbl, -1, sizeof tbl);

		for(int i = 1; i <= h; ++i){
			scanf(" %s", field[i] + 1);
			field[i][w+1] = '#';
		}

		if( !reachable() ){
			puts("-1");
			continue;
		}

		if( field[1][1] == '.' ){
			field[1][1] = '~';
		}
		if( field[h][w] == '.' ){
			field[h][w] = '~';
		}

		ps.clear();
		cs.clear();
		for(int i = 1; i <= h; ++i){
			for(int j = 1; j <= w; ++j){
				if( field[i][j] == '.' ){
					tbl[i][j] = -2;
				}
				else if( field[i][j] != '#' ){
					tbl[i][j] = ps.size();
					ps.push_back(i << 8 | j);
					cs.push_back( field[i][j] );
				}
			}
		}

		for(int i = 0; i < ps.size(); ++i){
			for(int j = 0; j < ps.size(); ++j){
				dp[i][j] = i == j ? 0 : -10000;
			}
		}

		vector<vector<int> > G(ps.size());
		vector<vector<int> > rG(ps.size());
		for(int i = 0; i < ps.size(); ++i){
			add_edge(ps[i], G[i]);

			for(it1 = G[i].begin(); it1 != G[i].end(); ++it1){
				rG[*it1].push_back(i);
				dp[i][*it1] = (cs[i] == cs[*it1] + 32);
			}
		}

		for(int d = 2; d < ps.size(); ++d)
		for(int i = 0; i + d < ps.size(); ++i){
			int j = i + d;

			int t = dp[i][j];

			if( cs[i] == cs[j] + 32 ){
				for(it1 = G[i].begin(); it1 != G[i].end(); ++it1)
				for(it2 = rG[j].begin(); it2 != rG[j].end(); ++it2){
					t = max(t, dp[*it1][*it2] + 1);
				}
			}

			for(int k = i; k < j; ++k){
				t = max(t, dp[i][k] + dp[k][j]);
			}
			dp[i][j] = t;
		}

		printf("%d\n", dp[0][ps.size() - 1] );

	}
}
### Prompt

Please create a solution in Cpp to the following problem:

Problem Statement

There is a maze which can be described as a W \times H grid. The upper-left cell is denoted as (1, 1), and the lower-right cell is (W, H). You are now at the cell (1, 1) and have to go to the cell (W, H). However, you can only move to the right adjacent cell or to the lower adjacent cell. The following figure is an example of a maze.


...#......
a###.#####
.bc...A...
.#C#d#.#
.#B#.#.###
.#...#e.D.
.#A..###.#
..e.c#..E.
d###.#
....#.#.#
E...d.C.


In the maze, some cells are free (denoted by `.`) and some cells are occupied by rocks (denoted by `#`), where you cannot enter. Also there are jewels (denoted by lowercase alphabets) in some of the free cells and holes to place jewels (denoted by uppercase alphabets). Different alphabets correspond to different types of jewels, i.e. a cell denoted by `a` contains a jewel of type A, and a cell denoted by `A` contains a hole to place a jewel of type A. It is said that, when we place a jewel to a corresponding hole, something happy will happen.

At the cells with jewels, you can choose whether you pick a jewel or not. Similarly, at the cells with holes, you can choose whether you place a jewel you have or not. Initially you do not have any jewels. You have a very big bag, so you can bring arbitrarily many jewels. However, your bag is a stack, that is, you can only place the jewel that you picked up last.

On the way from cell (1, 1) to cell (W, H), how many jewels can you place to correct holes?



Input

The input contains a sequence of datasets. The end of the input is indicated by a line containing two zeroes. Each dataset is formatted as follows.


H W
C_{11} C_{12} ... C_{1W}
C_{21} C_{22} ... C_{2W}
...
C_{H1} C_{H2} ... C_{HW}


Here, H and W are the height and width of the grid. You may assume 1 \leq W, H \leq 50. The rest of the datasets consists of H lines, each of which is composed of W letters. Each letter C_{ij} specifies the type of the cell (i, j) as described before. It is guaranteed that C_{11} and C_{WH} are never `#`.

You may also assume that each lowercase or uppercase alphabet appear at most 10 times in each dataset.

Output

For each dataset, output the maximum number of jewels that you can place to corresponding holes. If you cannot reach the cell (W, H), output -1.

Examples

Input

3 3
ac#
b#C
.BA
3 3
aaZ
a#Z
aZZ
3 3
..#
.#.
#..
1 50
abcdefghijklmnopqrstuvwxyYXWVUTSRQPONMLKJIHGFEDCBA
1 50
aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyY
1 50
abcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXY
1 50
aaaaaaaaaabbbbbbbbbbcccccCCCCCBBBBBBBBBBAAAAAAAAAA
10 10
...#......
a###.#####
.bc...A...
##.#C#d#.#
.#B#.#.###
.#...#e.D.
.#A..###.#
..e.c#..E.
####d###.#
##E...D.C.
0 0


Output

2
0
-1
25
25
1
25
4


Input

3 3
ac#
b#C
.BA
3 3
aaZ
a#Z
aZZ
3 3
..#
.#.
..
1 50
abcdefghijklmnopqrstuvwxyYXWVUTSRQPONMLKJIHGFEDCBA
1 50
aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyY
1 50
abcdefghijklmnopqrstuvwxyABCDEFGHIJKLMNOPQRSTUVWXY
1 50
aaaaaaaaaabbbbbbbbbbcccccCCCCCBBBBBBBBBBAAAAAAAAAA
10 10
...#......
a###.#####
.bc...A...
.#C#d#.#
.#B#.#.###
.#...#e.D.
.#A..###.#
..e.c#..E.
d###.#
E...D.C.
0 0


Output

2
0
-1
25
25
1
25
4

### Response

```cpp
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cfloat>
#include <cstring>
#include <cctype>
#include <queue>
using namespace std;


int h, w;
char field[52][52];
int tbl[52][52];
vector<int> ps;
vector<char> cs;
int dp[522][522];

bool reachable(){
	bool visit[52][52] = {};
	queue<int> q;
	q.push(1 << 8 | 1);
	while( !q.empty() ){
		int y = q.front() >> 8;
		int x = q.front() & 255;
		q.pop();
		if(y == h && x == w) return true;

		if( field[y + 1][x] != '#' ){
			if( !visit[y+1][x] ){
				visit[y+1][x] = true;
				q.push(y + 1 << 8 | x);
			}
		}
		if( field[y][x + 1] != '#' ){
			if( !visit[y][x+1] ){
				visit[y][x+1] = true;
				q.push(y << 8 | x + 1);
			}
		}
	}
	return false;
}

void add_edge(int p, vector<int> &e){
	bool visit[52][52] = {};
	queue<int> q;
	q.push(p);

	while( !q.empty() ){
		p = q.front();
		q.pop();

		int y = p >> 8;
		int x = p & 255;
		
		for(int i = 0; i < 2; ++i){
			int ny = y + i;
			int nx = x + (1 - i);

			if( !visit[ny][nx] ){
				visit[ny][nx] = true;
				if( tbl[ny][nx] != -1 ){
					if( tbl[ny][nx] == -2 ){
						q.push(ny << 8 | nx);
					}
					else{
						e.push_back(tbl[ny][nx]);
					}
				}
			}
		}
	}
}


int main(){
	vector<int>::iterator it1, it2;

	while( scanf("%d%d", &h, &w), h != 0 ){
		memset(field, '#', sizeof field);
		memset(tbl, -1, sizeof tbl);

		for(int i = 1; i <= h; ++i){
			scanf(" %s", field[i] + 1);
			field[i][w+1] = '#';
		}

		if( !reachable() ){
			puts("-1");
			continue;
		}

		if( field[1][1] == '.' ){
			field[1][1] = '~';
		}
		if( field[h][w] == '.' ){
			field[h][w] = '~';
		}

		ps.clear();
		cs.clear();
		for(int i = 1; i <= h; ++i){
			for(int j = 1; j <= w; ++j){
				if( field[i][j] == '.' ){
					tbl[i][j] = -2;
				}
				else if( field[i][j] != '#' ){
					tbl[i][j] = ps.size();
					ps.push_back(i << 8 | j);
					cs.push_back( field[i][j] );
				}
			}
		}

		for(int i = 0; i < ps.size(); ++i){
			for(int j = 0; j < ps.size(); ++j){
				dp[i][j] = i == j ? 0 : -10000;
			}
		}

		vector<vector<int> > G(ps.size());
		vector<vector<int> > rG(ps.size());
		for(int i = 0; i < ps.size(); ++i){
			add_edge(ps[i], G[i]);

			for(it1 = G[i].begin(); it1 != G[i].end(); ++it1){
				rG[*it1].push_back(i);
				dp[i][*it1] = (cs[i] == cs[*it1] + 32);
			}
		}

		for(int d = 2; d < ps.size(); ++d)
		for(int i = 0; i + d < ps.size(); ++i){
			int j = i + d;

			int t = dp[i][j];

			if( cs[i] == cs[j] + 32 ){
				for(it1 = G[i].begin(); it1 != G[i].end(); ++it1)
				for(it2 = rG[j].begin(); it2 != rG[j].end(); ++it2){
					t = max(t, dp[*it1][*it2] + 1);
				}
			}

			for(int k = i; k < j; ++k){
				t = max(t, dp[i][k] + dp[k][j]);
			}
			dp[i][j] = t;
		}

		printf("%d\n", dp[0][ps.size() - 1] );

	}
}
```