Language: C++

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

using pi = pair<int,int>;

const int dx[2]={1,0}, dy[2]={0,1};
const int ALP = 26;

int main(){
    int h,w;
    while(cin >>h >>w,h){
        vector<string> c(h);
        rep(i,h) cin >>c[i];

        vector<pi> p;
        map<pi,int> p2id;
        vector<int> s[ALP],t[ALP];
        rep(i,h)rep(j,w){
            if(islower(c[i][j])){
                p.pb({i,j});
                p2id[p.back()] = p2id.size();
                s[c[i][j]-'a'].pb(p2id[p.back()]);
            }
            else if(isupper(c[i][j])){
                p.pb({i,j});
                p2id[p.back()] = p2id.size();
                t[c[i][j]-'A'].pb(p2id[p.back()]);
            }
        }

        auto IN = [&](int y, int x){
            return 0<=y && y<h && 0<=x && x<w;
        };

        auto BFS = [&](pi start){
            vector<vector<bool>> vis(h,vector<bool>(w));
            vis[start.fi][start.se] = true;
            queue<pi> que;
            que.push(start);
            while(!que.empty()){
                pi now = que.front();
                que.pop();
                rep(d,2){
                    int ny = now.fi+dy[d], nx = now.se+dx[d];
                    if(IN(ny,nx) && c[ny][nx]!='#' && !vis[ny][nx]){
                        vis[ny][nx] = true;
                        que.push({ny,nx});
                    }
                }
            }
            return vis;
        };

        vector<vector<bool>> reach_check = BFS({0,0});
        if(!reach_check[h-1][w-1]){
            cout << -1 << endl;
            continue;
        }

        int n = p.size();
        // can move from i to j ?
        vector<vector<bool>> mv(n,vector<bool>(n));
        rep(i,n){
            vector<vector<bool>> vis = BFS(p[i]);
            rep(j,n) mv[i][j] = vis[p[j].fi][p[j].se];
            mv[i][i] = false;
        }

        vector<vector<int>> dp(n,vector<int>(n,-1));
        rep(i,ALP){
            for(int from:s[i])for(int to:t[i])if(mv[from][to]) dp[from][to] = 1;
        }

        // rep(loop,50){
        //     rep(i,ALP)for(int from:s[i])for(int to:t[i]){
        //         if(!mv[from][to]) continue;

        //         rep(j,ALP){
        //             for(int x:s[j]){
        //                 if(!mv[from][x]) continue;
        //                 for(int y:t[j]){
        //                     if(mv[x][y] && mv[y][to]) dp[from][to] = max(dp[from][to], dp[x][y]+1);
        //                 }
        //             }
        //         }
        //     }
        // }

        // vector<vector<int>> ans(h,vector<int>(w,-1));
        // ans[0][0] = 0;
        // rep(i,h)rep(j,w){
        //     rep(d,2){
        //         int ni = i+dy[d], nj = j+dx[d];
        //         if(IN(ni,nj) && c[ni][nj]!='#') ans[ni][nj] = max(ans[ni][nj], ans[i][j]);
        //     }

        //     if(islower(c[i][j])){
        //         int from = p2id[{i,j}];
        //         for(int to:t[c[i][j]-'a']){
        //             if(mv[from][to]){
        //                 ans[p[to].fi][p[to].se] = max(ans[p[to].fi][p[to].se], ans[i][j]+dp[from][to]);
        //             }
        //         }
        //     }
        // }
        cout << ans[h-1][w-1] << endl;
    }
    return 0;
}



Compiler output:
a.cc: In function 'int main()':
a.cc:115:17: error: 'ans' was not declared in this scope; did you mean 'abs'?
  115 |         cout << ans[h-1][w-1] << endl;
      |                 ^~~
      |                 abs