/*
    目標串是有U個大寫字母,L個小寫字母
    給出P個合法的字母對(a,b)   
    表示目標串相鄰的字母必滿足這些字母對,不能由其他組成
    問有多少種可能的目標串
    U,L <= 250
    P <= 200

    我比較土,總共52個字母,建立52個點的圖
    狀態是(pos, u, l) 在點pos處,還剩下u個大寫,l個小寫的總數
    
    其實O(ULP)的dp即可   (我之前也有想過的,但是轉移我居然是枚舉字母來轉移52*52,然后就放棄了)
    轉移應該是枚舉字母對!!! 總共P個

*/

#include
<iostream>
#include
<cstring>
#include
<map>
#include
<algorithm>
#include
<stack>
#include
<queue>
#include
<cmath>
#include
<string>
#include
<cstdlib>
#include
<vector>
#include
<cstdio>
#include
<set>
#include
<list>
#include
<numeric>
#include
<cassert>
#include
<ctime>

using namespace std;

const int MOD = 97654321;

char validPair[201][3];
int dp[251][251][52];

inline 
int get(char ch){
    
return isupper(ch) ? 26+ch-'A' : ch-'a';
}


int main()
{
#ifndef ONLINE_JUDGE
    freopen(
"in","r",stdin);
#endif

    
for(int U, L, P; ~scanf("%d%d%d"&U, &L, &P); ){
        
for(int i = 0 ; i < P ; i++){
            scanf(
"%s", validPair[i]);
            
//先get完,后面在計算時就不用再次get快很多
            validPair[i][0= get(validPair[i][0]);
            validPair[i][
1= get(validPair[i][1]);
        }

        memset(dp, 
0sizeof dp);
        
for(int j = 0 ; j < 52 ; j++){
            dp[(j
>=26)][(j<26)][j] = 1;
        }

        
for(int u = 0 ; u <= U ; u ++){
            
for(int l = 0; l <= L ; l++){
                
if(u+<= 1){
                    
continue;
                }

                
for(int i = 0; i < P ; i++){
                    
int first = validPair[i][0];
                    
int second = validPair[i][1];
                    
if(second < 26 && l > 0){
                        dp[u][l][second] 
+= dp[u][l-1][first];
                        dp[u][l][second] 
%= MOD;
                    }

                    
if(second >= 26 && u > 0){
                        dp[u][l][second] 
+= dp[u-1][l][first];
                        dp[u][l][second] 
%= MOD;
                    }


                }

            }

        }

        printf(
"%lld\n", accumulate(dp[U][L], dp[U][L]+52, 0LL) % MOD);
    }

    
return 0;
}