/*
    目标串是有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;
}