Problem:
Problem Statement
You have a grid with $H$ rows and $W$ columns. Each cell contains one of the following 11 characters: an addition operator
+
, a multiplication operator
*
, or a digit between $1$ and $9$.
There are paths from the top-left cell to the bottom-right cell by moving right or down $H+W-2$ times. Let us define the value of a path by the evaluation result of the mathematical expression you can obtain by concatenating all the characters contained in the cells on the path in order.
Your task is to compute the sum of values of any possible paths. Since the sum can be large, find it modulo $M$.
It is guaranteed the top-left cell and the bottom-right cell contain digits. Moreover, if two cells share an edge, at least one of them contains a digit. In other words, each expression you can obtain from a path is mathematically valid.
Input
The input consists of a single test case in the format below.
$H$ $W$ $M$
$a_{1,1}$ $\cdots$ $a_{1,W}$
$\ldots$
$a_{H,1}$ $\cdots$ $a_{H,W}$
The first line consists of three integers $H$, $W$ and $M$ ($1 \le H,W \le 2 000$, $2 \le M \le 10^{9}$).The following $H$ lines represent the characters on the grid. $a_{i,j}$ represents the character contained in the cell at the $i$-th row and $j$-th column. Each $a_{i,j}$ is either
+
,
*
, or a digit between $1$ and $9$. $a_{1,1}$ and $a_{H,W}$ are both digits. If two cells share an edge, at least one of them contain a digit.
Output
Print the sum of values of all possible paths modulo $M$.
Examples
Input
Output
2 3 1000
3*1
+27
162
4 4 3000000
24+7
*23*
9+48
*123
2159570

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

int main() {
    cin.tie(0)->sync_with_stdio(0);
    int h, w; ll m; cin >> h >> w >> m;
    V<string> a(h);
    REP(i, h) cin >> a[i];
    struct State {
        ll expr;
        ll term;
        ll num;
        ll weight;
    };
    auto sum = [&](State s1, State s2) {
        State ret;
        ret.expr = (s1.expr + s2.expr) % m;
        ret.term = (s1.term + s2.term) % m;
        ret.num = (s1.num + s2.num) % m;
        ret.weight = (s1.weight + s2.weight) % m;
        return ret;
    };
    V<V<State>> dp(h, V<State>(w));
    dp[0][0] = {0LL, 1LL, (a[0][0]-'0') % m, 1LL};
    REP(i, h) REP(j, w) {
        if(i==0 && j==0) continue;
        if(i == 0) dp[i][j] = dp[i][j-1];
        else if(j == 0) dp[i][j] = dp[i-1][j];
        else dp[i][j] = sum(dp[i-1][j], dp[i][j-1]);
        if(a[i][j] == '+') dp[i][j] = {
            (dp[i][j].expr + dp[i][j].num) % m,
            dp[i][j].weight,
            0LL,
            dp[i][j].weight
        };
        else if(a[i][j] == '*') dp[i][j] = {
            dp[i][j].expr,
            dp[i][j].num,
            0LL,
            dp[i][j].weight
        };
        else dp[i][j] = {
            dp[i][j].expr,
            dp[i][j].term,
            (dp[i][j].num * 10LL + dp[i][j].term * (a[i][j]-'0')) % m,
            dp[i][j].weight
        };
    }
    cout << (dp[h-1][w-1].expr + dp[h-1][w-1].num) % m << '\n';
}
accuracy: 1
time_ms: 70
memory_kb: 126336
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1ll << 60;
#define REP(i, n) for (ll i=0; i<ll(n); i++)
template <class T> using V = vector<T>;
template<class A, class B>
bool chmax(A &a, B b) { return a < b && (a = b, true); }
template<class A, class B>
bool chmin(A &a, B b) { return b < a && (a = b, true); }

int main() {
    cin.tie(0)->sync_with_stdio(0);
    int h, w; ll m; cin >> h >> w >> m;
    V<string> a(h);
    REP(i, h) cin >> a[i];
    struct State {
        ll expr;
        ll term;
        ll num;
        ll weight;
    };
    auto sum = [&](State s1, State s2) {
        State ret;
        ret.expr = s1.expr + s2.expr;
        ret.term = s1.term + s2.term;
        ret.num = s1.num + s2.num;
        ret.weight = s1.weight + s2.weight;
        return ret;
    };
    V<V<State>> dp(h, V<State>(w));
    dp[0][0] = {0LL, 1LL, (a[0][0]-'0') % m, 1LL};
    REP(i, h) REP(j, w) {
        if(i==0 && j==0) continue;
        if(i == 0) dp[i][j] = dp[i][j-1];
        else if(j == 0) dp[i][j] = dp[i-1][j];
        else dp[i][j] = sum(dp[i-1][j], dp[i][j-1]);
        if(a[i][j] == '+') dp[i][j] = {
            (dp[i][j].expr + dp[i][j].num) % m,
            dp[i][j].weight,
            0LL,
            dp[i][j].weight
        };
        else if(a[i][j] == '*') dp[i][j] = {
            dp[i][j].expr,
            dp[i][j].num,
            0LL,
            dp[i][j].weight
        };
        else dp[i][j] = {
            dp[i][j].expr,
            dp[i][j].term,
            (dp[i][j].num * 10LL + dp[i][j].term * (a[i][j]-'0')) % m,
            dp[i][j].weight
        };
    }
    cout << (dp[h-1][w-1].expr + dp[h-1][w-1].num) % m << '\n';
}
accuracy: 0.15
time_ms: 40
memory_kb: 98688
final_rank: 19

code_snippet: #include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define vec vector
#define iter iterator
#define pii pari<int,int>
#define REP(i,x,y) for (int i=x;i<=y;i++)
#define DWN(i,x,y) for (int i=x;i>=y;i--)
using namespace std;
template<class Tp>Tp mymin(Tp x,Tp y){
    return x<y?x:y;
}
#define min mymin
template<class Tp>Tp mymax(Tp x,Tp y){
    return x<y?y:x;
}
#define max mymax
template<class Tp>Tp myabs(Tp x){
    return x<0?-x:x;
}
#define abs myabs
template<class Tp>void myswap(Tp &x,Tp &y){
    Tp z=x;x=y,y=z;
}
#define swap myswap
template<class Tp>Tp read(){
    Tp res=0,f_f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f_f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') res=(res<<3)+(res<<1)-'0'+ch,ch=getchar();
    return res*f_f;
}
#define iread() (read<int>())
#define lread() (read<long long>())
#define uread() (read<unsigned long long>())
const int maxn=2005;
int n,m,a[maxn][maxn];
int sum[maxn][maxn],mul[maxn][maxn],num[maxn][maxn],tot[maxn][maxn];
ll p;
inline void get_modu(int &x){
    while(x>=p) x-=p;
}
#define Gmo get_modu
inline void solve_way(int x,int y,int tx,int ty){
    tot[tx][ty]+=tot[x][y],Gmo(tot[tx][ty]);
    sum[tx][ty]+=sum[x][y],Gmo(sum[tx][ty]);
}
inline void solve_num(int x,int y,int tx,int ty){
    solve_way(x,y,tx,ty);
    if(a[tx][ty]>0){
        mul[tx][ty]+=mul[x][y],Gmo(mul[tx][ty]);
        num[tx][ty]+=(1ll*num[x][y]*10%p+1ll*mul[x][y]*a[tx][ty]%p)%p,Gmo(num[tx][ty]);
    }
    else if(a[tx][ty]==-1){
        sum[tx][ty]+=num[x][y],Gmo(sum[tx][ty]);
    }
    else if(a[tx][ty]==-2){
        mul[tx][ty]+=num[x][y],Gmo(mul[tx][ty]);
    }
}
inline void solve_add(int x,int y,int tx,int ty){
    solve_way(x,y,tx,ty);
    mul[tx][ty]+=tot[x][y],Gmo(mul[tx][ty]);
    num[tx][ty]+=1ll*tot[x][y]*a[tx][ty]%p,Gmo(num[tx][ty]);
}
inline void solve_mul(int x,int y,int tx,int ty){
    solve_way(x,y,tx,ty);
    mul[tx][ty]+=mul[x][y],Gmo(mul[tx][ty]);
    num[tx][ty]+=1ll*mul[x][y]*a[tx][ty]%p,Gmo(num[tx][ty]);
}
int main(){
    n=iread(),m=iread(),p=lread();
    REP(i,1,n){
        REP(j,1,m){
            char ch=getchar();
            while(!isdigit(ch)&&ch!='+'&&ch!='*') ch=getchar();
            if(isdigit(ch)) a[i][j]=ch-'0';
            else if(ch=='+') a[i][j]=-1;
            else if(ch=='*') a[i][j]=-2;
        }
    }
    mul[1][1]=1,num[1][1]=a[1][1],tot[1][1]=1;
    REP(i,1,n){
        REP(j,1,m){
            if(a[i][j]>0){
                if(i<n) solve_num(i,j,i+1,j);
                if(j<m) solve_num(i,j,i,j+1);
            }
            else if(a[i][j]==-1){
                if(i<n) solve_add(i,j,i+1,j);
                if(j<m) solve_add(i,j,i,j+1);
            }
            else if(a[i][j]==-2){
                if(i<n) solve_mul(i,j,i+1,j);
                if(j<m) solve_mul(i,j,i,j+1);
            }
        }
    }
    int ans=sum[n][m];
    ans+=num[n][m],Gmo(ans);
    printf("%d\n",ans);
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 81932
final_rank: 4

code_snippet: #include<bits/stdc++.h>
#define int long long
#define ll long long
#define ull unsigned long long
#define vec vector
#define iter iterator
#define pii pari<int,int>
#define REP(i,x,y) for (int i=x;i<=y;i++)
#define DWN(i,x,y) for (int i=x;i>=y;i--)
using namespace std;
template<class Tp>Tp mymin(Tp x,Tp y){
    return x<y?x:y;
}
#define min mymin
template<class Tp>Tp mymax(Tp x,Tp y){
    return x<y?y:x;
}
#define max mymax
template<class Tp>Tp myabs(Tp x){
    return x<0?-x:x;
}
#define abs myabs
template<class Tp>void myswap(Tp &x,Tp &y){
    Tp z=x;x=y,y=z;
}
#define swap myswap
template<class Tp>Tp read(){
    Tp res=0,f_f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f_f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') res=(res<<3)+(res<<1)-'0'+ch,ch=getchar();
    return res*f_f;
}
#define iread() (read<int>())
#define lread() (read<long long>())
#define uread() (read<unsigned long long>())
const int maxn=2005;
int n,m,p,a[maxn][maxn];
int sum[maxn][maxn],mul[maxn][maxn],num[maxn][maxn],tot[maxn][maxn];
inline void get_modu(int &x){
    while(x>=p) x-=p;
}
#define Gmo get_modu
inline void solve_way(int x,int y,int tx,int ty){
    tot[tx][ty]+=tot[x][y],Gmo(tot[tx][ty]);
    sum[tx][ty]+=sum[x][y],Gmo(sum[tx][ty]);
}
inline void solve_num(int x,int y,int tx,int ty){
    solve_way(x,y,tx,ty);
    if(a[tx][ty]>0){
        mul[tx][ty]+=mul[x][y],Gmo(mul[tx][ty]);
        num[tx][ty]+=(1ll*num[x][y]*10%p+1ll*mul[x][y]*a[tx][ty]%p)%p,Gmo(num[tx][ty]);
    }
    else if(a[tx][ty]==-1){
        sum[tx][ty]+=num[x][y],Gmo(sum[tx][ty]);
    }
    else if(a[tx][ty]==-2){
        mul[tx][ty]+=num[x][y],Gmo(mul[tx][ty]);
    }
}
inline void solve_add(int x,int y,int tx,int ty){
    solve_way(x,y,tx,ty);
    mul[tx][ty]+=tot[x][y],Gmo(mul[x][y]);
    num[tx][ty]+=1ll*tot[x][y]*a[tx][ty]%p,Gmo(num[tx][ty]);
}
inline void solve_mul(int x,int y,int tx,int ty){
    solve_way(x,y,tx,ty);
    mul[tx][ty]+=mul[x][y],Gmo(mul[tx][ty]);
    num[tx][ty]+=1ll*mul[x][y]*a[tx][ty]%p,Gmo(num[tx][ty]);
}
signed main(){
    n=iread(),m=iread(),p=iread();
    REP(i,1,n){
        REP(j,1,m){
            char ch=getchar();
            while(!isdigit(ch)&&ch!='+'&&ch!='*') ch=getchar();
            if(isdigit(ch)) a[i][j]=ch-'0';
            else if(ch=='+') a[i][j]=-1;
            else if(ch=='*') a[i][j]=-2;
        }
    }
    mul[1][1]=1,num[1][1]=a[1][1],tot[1][1]=1;
    REP(i,1,n){
        REP(j,1,m){
            if(a[i][j]>0){
                if(i<n) solve_num(i,j,i+1,j);
                if(j<m) solve_num(i,j,i,j+1);
            }
            else if(a[i][j]==-1){
                if(i<n) solve_add(i,j,i+1,j);
                if(j<m) solve_add(i,j,i,j+1);
            }
            else if(a[i][j]==-2){
                if(i<n) solve_mul(i,j,i+1,j);
                if(j<m) solve_mul(i,j,i,j+1);
            }
        }
    }
/*
    REP(i,1,n){
        REP(j,1,m){
            printf("a[%d][%d]:",i,j);
            if(a[i][j]>0) printf("%d ",a[i][j]);
            else if(a[i][j]==-1) printf("+ ");
            else if(a[i][j]==-2) printf("* ");
            printf("sum[%d][%d]:%3d ",i,j,sum[i][j]);
            printf("tot[%d][%d]:%3d ",i,j,tot[i][j]);
            printf("mul[%d][%d]:%3d ",i,j,mul[i][j]);
            printf("num[%d][%d]:%3d\n",i,j,num[i][j]);
        }
    }
*/
    int ans=sum[n][m];
    ans+=num[n][m],Gmo(ans);
    printf("%lld\n",ans);
    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 160412
final_rank: 9

code_snippet: #include<bits/stdc++.h>
#define int long long 
using namespace std;
const int N=2e3+5;
int n,m,f[N][N],mul[N][N],lst[N][N],g[N][N],P;
string s[N];
#undef int 
int main(){
#define int long long 
	ios::sync_with_stdio(0),cin.tie(0);
	cin>>n>>m>>P;
	for(int i=1;i<=n;i++)cin>>s[i],s[i]='#'+s[i];
	mul[1][1]=1,lst[1][1]=s[1][1]-'0',g[1][1]=1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(i==1&&j==1)continue;
			if(s[i][j]=='*'){
				f[i][j]=(f[i][j]+f[i-1][j]+f[i][j-1])%P;
				mul[i][j]=(mul[i][j]+lst[i-1][j]+lst[i][j-1])%P;
				lst[i][j]=0;
				g[i][j]=(g[i][j]+g[i-1][j]+g[i][j-1])%P;
			}
			if(s[i][j]=='+'){
				f[i][j]=(f[i][j]+(f[i-1][j]+lst[i-1][j])%P+(f[i][j-1]+lst[i][j-1])%P)%P;
				mul[i][j]=(g[i-1][j]+g[i][j-1])%P;
				lst[i][j]=0;
				g[i][j]=(g[i][j]+g[i-1][j]+g[i][j-1])%P;
			}
			if(isdigit(s[i][j])){
				f[i][j]=(f[i][j]+f[i-1][j]+f[i][j-1])%P;
				mul[i][j]=(mul[i][j]+mul[i-1][j]+mul[i][j-1])%P;
				lst[i][j]=(lst[i][j]+(lst[i-1][j]*10%P+mul[i-1][j]*(s[i][j]-'0')%P)%P+(lst[i][j-1]*10%P+mul[i][j-1]*(s[i][j]-'0')%P)%P)%P;
				g[i][j]=(g[i][j]+g[i-1][j]+g[i][j-1])%P;
			}
		}
	}
	cout<<(f[n][m]+lst[n][m])%P<<'\n';
	
	return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 132296
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ll = long long;

ll mod;

int c, n, m;
char m0[2010][2010];

struct node{
	/*
	a: 最后连乘（不含最后一个）的和
	b: 最后连乘（含最后一个）的和
	pre: 连乘之前的和
	cnt: 方案数 
	*/
	ll a, b, pre, cnt;
	node operator+(const node y) const {
		return {(a+y.a)%mod, (b+y.b)%mod, (pre+y.pre)%mod, (cnt+y.cnt)%mod};
	}
}f[2010][2010][2];
/*
f[i][j][next_char]
0: number
1: symbol

===== transformTable =====
||$0$|$1\sim9$|符号|
|:-:|:-:|:-:|:--:|
|$0$|$0/1$|$0/1$|$0$|
|$1\sim9$|$0/1$|$0/1$|$0$|
|符号|$1$|$0/1$|无法转移|
*/

node trans(node *arr, char cur) {
	node src = arr[!isdigit(cur)];
	if (isdigit(cur)) return {src.a, (src.b*10+(cur&0xf)*src.a)%mod, src.pre, src.cnt};
	if (cur == '+') return {src.cnt, 0, (src.pre+src.b)%mod, src.cnt};
	else return {src.b, 0, src.pre, src.cnt};
}

int getd(char cur) {
	if (isdigit(cur)) return (cur=='0'?0:1);
	return 2;
}

int main() {
//	freopen("number.in", "r", stdin);
//	freopen("number.out", "w", stdout);
	int T = 1;
//	scanf("%d%d", &c, &T);
	while (T--) {
		scanf("%d%d%lld", &n, &m, &mod);
		for (int i = 1; i <= n; i++) scanf("%s", m0[i]+1);
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				f[i][j][0] = f[i][j][1] = {0, 0, 0, 0};
			}
		}
		f[1][1][1] = {1, m0[1][1]&0xf, 0, 1};
		if (m0[1][1]&0xf) f[1][1][0] = {1, m0[1][1]&0xf, 0, 1};
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				for (int k = 0; k < 2; k++) {
					int nx = i+(int[]){0, 1}[k], ny = j+(int[]){1, 0}[k];
					if (nx > n || ny > m) continue;
					int p = getd(m0[i][j]), q = getd(m0[nx][ny]);
					if (p == 2 && q == 2) continue;
					if (!(p == 2 && q == 0)) f[nx][ny][0] = f[nx][ny][0]+trans(f[i][j], m0[nx][ny]);
					if (q != 2) f[nx][ny][1] = f[nx][ny][1]+trans(f[i][j], m0[nx][ny]);
				} 
			}
		}
		printf("%lld\n", (f[n][m][1].pre+f[n][m][1].b)%mod);
		/*
		- 不是我喜欢的题目，直接放弃
		- 哈哈
		- 那很讨厌了
		- 算我一个 
		*/
	}
}
accuracy: 1
time_ms: 510
memory_kb: 259620
final_rank: 15

code_snippet: #include<bits/stdc++.h>
using namespace std;
namespace cs{
	#define LL long long
	#define fir first
	#define sec second
	typedef pair<int,int> PII;
	const int N=2000;
	LL Mod;
	const int dx[2]={0,1},dy[2]={1,0};
	int Case,T=1,n,m;
	string s[N+5];
	LL val[N+5][N+5][2],mul[N+5][N+5][2],pre[N+5][N+5][2],f[N+5][N+5][2];
	inline void addmod(LL& x,LL y){x=(x+y)%Mod;}
	void Init(){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				val[i][j][0]=mul[i][j][0]=pre[i][j][0]=f[i][j][0]=0;
				val[i][j][1]=mul[i][j][1]=pre[i][j][1]=f[i][j][1]=0;
			}
		}
	}
	int main(){
		ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//		freopen("number.in","r",stdin);
//		freopen("number.out","w",stdout);
//		cin>>Case>>T;
		int x,y;
		char c,c1;
		while(T--){
			Init();
			cin>>n>>m>>Mod;
			for(int i=1;i<=n;i++){
				cin>>s[i];
				s[i]=' '+s[i];
			}
			if(s[1][1]=='0'){
				mul[1][1][1]=1;
				f[1][1][1]=1;
			}
			else{
				mul[1][1][0]=1;
				pre[1][1][0]=s[1][1]-'0';
				f[1][1][0]=1;
			}
			for(int i=1;i<=n;i++){
				for(int j=1;j<=m;j++){
					c=s[i][j];
					for(int k=0;k<2;k++){
						x=i+dx[k];
						y=j+dy[k];
						if(x>n||y>m) continue;
						c1=s[x][y];
						if(c1>='0'&&c1<='9'){
							if(c1=='0'&&(c=='+'||c=='*')){
								addmod(val[x][y][1],val[i][j][0]);
								addmod(mul[x][y][1],mul[i][j][0]);
								addmod(pre[x][y][1],pre[i][j][0]*10);
								addmod(f[x][y][1],f[i][j][0]);
							}
							else{
								addmod(val[x][y][0],val[i][j][0]);
								addmod(mul[x][y][0],mul[i][j][0]);
								addmod(pre[x][y][0],pre[i][j][0]*10+(c1-'0')*mul[i][j][0]);
								addmod(f[x][y][0],f[i][j][0]);
							}
						}
						else if(c1=='*'){
							if(c!='+'&&c!='*'){
								addmod(val[x][y][0],val[i][j][0]+val[i][j][1]);
								addmod(mul[x][y][0],pre[i][j][0]+pre[i][j][1]);
								addmod(f[x][y][0],f[i][j][0]+f[i][j][1]);
							}
						}else{
							if(c!='+'&&c!='*'){
								addmod(val[x][y][0],val[i][j][0]+pre[i][j][0]+val[i][j][1]+pre[i][j][1]);
								addmod(mul[x][y][0],f[i][j][0]+f[i][j][1]);
								addmod(f[x][y][0],f[i][j][0]+f[i][j][1]);
							}
						}
					}
				}
			}
			cout<<(val[n][m][0]+pre[n][m][0]+val[n][m][1]+pre[n][m][1])%Mod<<"\n";
		}
		return 0;
	}
}
int main(){
	cs::main();
	return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 257796
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
char a[2005][2005];
int n, m, mod, f[2005][2005][2], g[2005][2005][2], h[2005][2005][2], dp[2005][2005][2];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m >> mod;
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++)
			cin >> a[i][j];
	if(a[1][1] == '+' || a[1][1] == '*')
		cout << 0, exit(0);
	for(int k : {0, 1})
		f[1][1][k] = g[1][1][k] = h[1][1][k] = dp[1][1][k] = 0;
	g[1][1][a[1][1] == '0'] = a[1][1] - '0', h[1][1][a[1][1] == '0'] = dp[1][1][a[1][1] == '0'] = 1;
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= m; j++) {
			if(i < 2 && j < 2)
				continue;
			if(a[i][j] == '+')
				for(int k : {0, 1}) {
					dp[i][j][k] = g[i][j][k] = f[i][j][k] = 0;
					if(i > 1 && a[i - 1][j] != '+' && a[i - 1][j] != '*')
						dp[i][j][k] = (dp[i][j][k] + dp[i - 1][j][k]) % mod, f[i][j][k] = (f[i - 1][j][k] + g[i - 1][j][k]) % mod;
					if(j > 1 && a[i][j - 1] != '+' && a[i][j - 1] != '*')
						dp[i][j][k] = (dp[i][j][k] + dp[i][j - 1][k]) % mod, f[i][j][k] = (f[i][j][k] + f[i][j - 1][k] + g[i][j - 1][k]) % mod;
					h[i][j][k] = dp[i][j][k];
				}
			else if(a[i][j] == '*') {
				for(int k : {0, 1}) {
					h[i][j][k] = g[i][j][k] = dp[i][j][k] = f[i][j][k] = 0;
					if(i > 1 && a[i - 1][j] != '+' && a[i - 1][j] != '*')
						dp[i][j][k] = (dp[i][j][k] + dp[i - 1][j][k]) % mod, h[i][j][k] = (h[i][j][k] + g[i - 1][j][k]) % mod, f[i][j][k] = f[i - 1][j][k];
					if(j > 1 && a[i][j - 1] != '+' && a[i][j - 1] != '*')
						dp[i][j][k] = (dp[i][j][k] + dp[i][j - 1][k]) % mod, h[i][j][k] = (h[i][j][k] + g[i][j - 1][k]) % mod, f[i][j][k] = (f[i][j][k] + f[i][j - 1][k]) % mod;
				}
			}
			else {
				for(int k : {0, 1})
					f[i][j][k] = g[i][j][k] = h[i][j][k] = dp[i][j][k] = 0;
				if(i > 1)
					if(a[i - 1][j] == '+' || a[i - 1][j] == '*') {
						g[i][j][a[i][j] == '0'] = (10ll * (g[i - 1][j][0] + g[i - 1][j][1]) + 1ll * (a[i][j] - '0') * (h[i - 1][j][0] + h[i - 1][j][1])) % mod;
						h[i][j][a[i][j] == '0'] = (h[i - 1][j][0] + h[i - 1][j][1]) % mod;
						dp[i][j][a[i][j] == '0'] = (dp[i - 1][j][0] + dp[i - 1][j][1]) % mod;
						f[i][j][a[i][j] == '0'] = (f[i - 1][j][0] + f[i - 1][j][1]) % mod;
					}
					else {
						g[i][j][0] = (10ll * g[i - 1][j][0] + 1ll * (a[i][j] - '0') * h[i - 1][j][0]) % mod;
						h[i][j][0] = h[i - 1][j][0];
						dp[i][j][0] = dp[i - 1][j][0];
						f[i][j][0] = f[i - 1][j][0];
					}
				if(j > 1)
					if(a[i][j - 1] == '+' || a[i][j - 1] == '*') {
						g[i][j][a[i][j] == '0'] = (g[i][j][a[i][j] == '0'] + 10ll * (g[i][j - 1][0] + g[i][j - 1][1]) + 1ll * (a[i][j] - '0') * (h[i][j - 1][0] + h[i][j - 1][1])) % mod;
						h[i][j][a[i][j] == '0'] = (h[i][j][a[i][j] == '0'] + h[i][j - 1][0] + h[i][j - 1][1]) % mod;
						dp[i][j][a[i][j] == '0'] = (dp[i][j][a[i][j] == '0'] + dp[i][j - 1][0] + dp[i][j - 1][1]) % mod;
						f[i][j][a[i][j] == '0'] = (f[i][j][a[i][j] == '0'] + f[i][j - 1][0] + f[i][j - 1][1]) % mod;
					}
					else {
						g[i][j][0] = (g[i][j][0] + 10ll * g[i][j - 1][0] + 1ll * (a[i][j] - '0') * h[i][j - 1][0]) % mod;
						h[i][j][0] = (h[i][j][0] + h[i][j - 1][0]) % mod;
						dp[i][j][0] = (dp[i][j][0] + dp[i][j - 1][0]) % mod;
						f[i][j][0] = (f[i][j][0] + f[i][j - 1][0]) % mod;
					}
			}
		}
	cout << (f[n][m][0] + g[n][m][0] + f[n][m][1]) % mod << '\n';
	return 0;
}
accuracy: 0.2125
time_ms: 100
memory_kb: 132820
final_rank: 17

code_snippet: #include<iostream>

using namespace std;

typedef long long i64;

int n,m,mod;
char a[2005][2005];

struct node{
    int ans,cnt,las,ex;
    inline int val()const{return (ans+cnt*las)%mod;}
    friend inline ostream& operator<<(ostream& os,const node &x){
        os<<'{'<<x.ans<<' '<<x.cnt<<' '<<x.las<<' '<<x.ex<<'}';
        return os;
    }
}dp[2005][2005][6];

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m>>mod;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            cin>>a[i][j];
            for(int S=0;S<6;++S)
                dp[i][j][S]={0,0,0,0};
        }
    dp[1][1][(a[1][1]=='0')<<1]={0,1,a[1][1]^48,0};
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            if(i==1&&j==1)
                continue;
            if(a[i][j]=='*'){
                i64 ans=0,cnt=0,ex=0;
                for(int S=0;S<4;++S){
                    ans+=dp[i-1][j][S].ans+dp[i][j-1][S].ans;
                    cnt+=dp[i-1][j][S].cnt+dp[i][j-1][S].cnt;
                    ex+=dp[i-1][j][S].las+dp[i][j-1][S].las;
                }
                dp[i][j][5]={(int)(ans%mod),(int)(cnt%mod),0,(int)(ex%mod)};
            }else if(a[i][j]=='+'){
                i64 ans=0,cnt=0;
                for(int S=0;S<4;++S){
                    ans+=dp[i-1][j][S].ans+dp[i-1][j][S].las+dp[i][j-1][S].ans+dp[i][j-1][S].las;
                    cnt+=dp[i-1][j][S].cnt+dp[i][j-1][S].cnt;
                }
                dp[i][j][4]={(int)(ans%mod),(int)(cnt%mod),0,0};
            }else if(a[i][j]=='0'){
                dp[i][j][0].ans=(dp[i-1][j][0].ans+dp[i][j-1][0].ans)%mod;
                dp[i][j][0].cnt=(dp[i-1][j][0].cnt+dp[i][j-1][0].cnt)%mod;
                dp[i][j][0].las=(dp[i-1][j][0].las+dp[i][j-1][0].las)*10ll%mod;
                dp[i][j][1].ans=(dp[i-1][j][1].ans+dp[i][j-1][1].ans)%mod;
                dp[i][j][1].cnt=(dp[i-1][j][1].cnt+dp[i][j-1][1].cnt)%mod;
                dp[i][j][1].las=(dp[i-1][j][1].las+dp[i][j-1][1].las)*10ll%mod;
                dp[i][j][1].ex=(dp[i-1][j][1].ex+dp[i][j-1][1].ex)%mod;
                dp[i][j][2].ans=(dp[i-1][j][4].ans+dp[i][j-1][4].ans)%mod;
                dp[i][j][2].cnt=(dp[i-1][j][4].cnt+dp[i][j-1][4].cnt)%mod;
                dp[i][j][3].ans=(dp[i-1][j][5].ans+dp[i][j-1][5].ans)%mod;
                dp[i][j][3].cnt=(dp[i-1][j][5].cnt+dp[i][j-1][5].cnt)%mod;
                dp[i][j][3].ex=(dp[i-1][j][5].ex+dp[i][j-1][5].ex)%mod;
            }else{
                i64 ans0=0,cnt0=0,las0=0,ans1=0,cnt1=0,las1=0,ex1=0;
                for(auto S:{0,4}){
                    ans0+=dp[i-1][j][S].ans+dp[i][j-1][S].ans;
                    cnt0+=dp[i-1][j][S].cnt+dp[i][j-1][S].cnt;
                    las0+=dp[i-1][j][S].las+dp[i][j-1][S].las;
                    ans1+=dp[i-1][j][S|1].ans+dp[i][j-1][S|1].ans;
                    cnt1+=dp[i-1][j][S|1].cnt+dp[i][j-1][S|1].cnt;
                    las1+=dp[i-1][j][S|1].las+dp[i][j-1][S|1].las;
                    ex1+=dp[i-1][j][S|1].ex+dp[i][j-1][S|1].ex;
                }
                ans0%=mod;cnt0%=mod;ans1%=mod;cnt1%=mod;ex1%=mod;
                las0=(las0*10+(a[i][j]^48)*cnt0)%mod;
                las1=(las1*10+ex1*(a[i][j]^48))%mod;
                dp[i][j][0]={(int)ans0,(int)cnt0,(int)las0,0};
                dp[i][j][1]={(int)ans1,(int)cnt1,(int)las1,(int)ex1};
            }
        }
    }
    i64 ans=0;
    for(int S=0;S<4;++S)
        ans+=dp[n][m][S].ans+dp[n][m][S].las;
    cout<<ans%mod<<'\n';
    return 0;
}
accuracy: 0.1625
time_ms: 180
memory_kb: 375380
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int N = 2005;
int n, m, mod; string s[N];
long long f[N][N][2], g[N][N][2], h[N][N][2], w[N][N][2];

long long F(int i, int j) { return (f[i][j][0] + f[i][j][1]) % mod; }
long long G(int i, int j) { return (g[i][j][0] + g[i][j][1]) % mod; }
long long H(int i, int j) { return (h[i][j][0] + h[i][j][1]) % mod; }
long long W(int i, int j) { return (w[i][j][0] + w[i][j][1]) % mod; }

int main() {
    ios :: sync_with_stdio(false), cin.tie(0);
    
    cin >> n >> m >> mod;
    for (int i = 1; i <= n; i++) {
        cin >> s[i]; s[i] = " " + s[i];
    }
    
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            f[i][j][0] = f[i][j][1] = 0;
            g[i][j][0] = g[i][j][1] = 0;
            h[i][j][0] = h[i][j][1] = 0;
            w[i][j][0] = w[i][j][1] = 0;
        }
    }
    
    g[1][1][s[1][1] == '0'] = 1;
    h[1][1][s[1][1] == '0'] = s[1][1] - '0';
    w[1][1][s[1][1] == '0'] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (i == 1 && j == 1) { continue; }
            if (s[i][j] == '+') {
                if (i > 1 && isdigit(s[i - 1][j])) {
                    f[i][j][0] = (f[i][j][0] + F(i - 1, j) + H(i - 1, j)) % mod;
                    w[i][j][0] = (w[i][j][0] + W(i - 1, j)) % mod;
                }
                if (j > 1 && isdigit(s[i][j - 1])) {
                    f[i][j][0] = (f[i][j][0] + F(i, j - 1) + H(i, j - 1)) % mod;
                    w[i][j][0] = (w[i][j][0] + W(i, j - 1)) % mod;
                }
                g[i][j][0] = w[i][j][0];
            } else if (s[i][j] == '*') {
                if (i > 1 && isdigit(s[i - 1][j])) {
                    f[i][j][0] = (f[i][j][0] + F(i - 1, j)) % mod;
                    g[i][j][0] = (g[i][j][0] + H(i - 1, j)) % mod;
                    w[i][j][0] = (w[i][j][0] + W(i - 1, j)) % mod;
                }
                if (j > 1 && isdigit(s[i][j - 1])) {
                    f[i][j][0] = (f[i][j][0] + F(i, j - 1)) % mod;
                    g[i][j][0] = (g[i][j][0] + H(i, j - 1)) % mod;
                    w[i][j][0] = (w[i][j][0] + W(i, j - 1)) % mod;
                }
            } else {
                int v = s[i][j] - '0';
                if (i > 1) {
                    int u = (!v && !isdigit(s[i - 1][j]));
                    f[i][j][u] = (f[i][j][u] + f[i - 1][j][0]) % mod;
                    g[i][j][u] = (g[i][j][u] + g[i - 1][j][0]) % mod;
                    h[i][j][u] = (h[i][j][u] + h[i - 1][j][0] * 10 + g[i - 1][j][0] * v) % mod;
                    w[i][j][u] = (w[i][j][u] + w[i - 1][j][0]) % mod;
                }
                if (j > 1) {
                    int l = (!v && !isdigit(s[i][j - 1]));
                    f[i][j][l] = (f[i][j][l] + f[i][j - 1][0]) % mod;
                    g[i][j][l] = (g[i][j][l] + g[i][j - 1][0]) % mod;
                    h[i][j][l] = (h[i][j][l] + h[i][j - 1][0] * 10 + g[i][j - 1][0] * v) % mod;
                    w[i][j][l] = (w[i][j][l] + w[i][j - 1][0]) % mod;
                }
            }
        }
    }
    cout << (F(n, m) + H(n, m)) % mod << "\n";
    
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 257776
final_rank: 13

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
using namespace std;

using i64 = long long;
#define rep(i,n) for(i64 i=0; i<i64(n); i++)

struct Node {
    i64 pTerm;
    i64 cterm;
    i64 li;
    i64 lo;
};

int MOD;

void madd(i64& l, i64 r){
    l += r; if(l >= MOD) l -= MOD;
}

Node& operator+=(Node& l, const Node& r){
    madd(l.pTerm,  r.pTerm);
    madd(l.cterm,  r.cterm);
    madd(l.li, r.li);
    madd(l.lo, r.lo);
    return l;
}

void testcase(){
    int H, W; cin >> H >> W;
    cin >> MOD;
    vector<Node> dp(W, {0,0,0,0});
    dp[0].li = 1; dp[0].pTerm = 1;
    for(i64 y=0; y<H; y++){
        string s; cin >> s;
        vector<Node> nx(W);
        rep(x,W){
            Node c = dp[x];
            if(x != 0) c += nx[x-1];
            nx[x].lo = c.lo;
            nx[x].li = c.li;
            if(s[x] == '+'){
                madd(nx[x].lo, c.cterm);
                nx[x].pTerm = nx[x].li;
                nx[x].cterm = 0;
            } else if(s[x] == '*'){
                nx[x].pTerm = c.cterm;
                nx[x].cterm = 0;
            } else {
                i64 d = s[x] - '0';
                nx[x].pTerm = c.pTerm;
                nx[x].cterm = (c.cterm * 10 + c.pTerm * d) % MOD;
            }
        }
        swap(dp, nx);
    }
    i64 ans = (dp.back().lo + dp.back().cterm) % MOD;
    cout << ans << "\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    testcase();
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3616
final_rank: 1

code_snippet: // AOJ #2973 Route Calculator Returns
// 2025.2.16
 
#include <bits/stdc++.h>
using namespace std;
using ll = long long; 

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cins(char t[]) { // 文字列の入力　スペース以下の文字で入力終了
    char *s = t;
	do *s = gc();
	while (*s++ > ' ');
	*(s-1) = 0;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int NMAX = 2005;
char ch[NMAX][NMAX];
int A[NMAX][NMAX], B[NMAX][NMAX], C[NMAX][NMAX], N[NMAX][NMAX];
int h, w, mod;

int main() {
	h = Cin(), w = Cin(), mod = Cin();
    
	for(int r = 1; r <= h; r++) Cins(ch[r]+1);
	
	A[1][1] = 0, B[1][1] = 1, C[1][1] = ch[1][1] & 0xf, N[1][1] = 1;
    for(int r = 1; r <= h; r++){
    	for(int c = 1; c <= w; c++){
			if(c == 1 && r == 1) continue;
            char cc = ch[r][c];

			ll A1 = A[r][c-1], A2 = A[r-1][c];
			ll B1 = B[r][c-1], B2 = B[r-1][c];
			ll C1 = C[r][c-1], C2 = C[r-1][c];
			ll N1 = N[r-1][c], N2 = N[r][c-1];
			

			if(isdigit(cc)) {
                cc &= 0xf;
				C1 = (C1 * 10) % mod;
				C2 = (C2 * 10) % mod;
				C1 = (C1 + B1 * cc) % mod;
				C2 = (C2 + B2 * cc) % mod;
			} else {
				if(cc == '*' || cc == '+'){
					B1 = C1, B2 = C2;
					C1 = C2 = 0;
				}
				if(cc == '+'){
					A1 = (A1 + B1) % mod;
					A2 = (A2 + B2) % mod;
					B1 = N1;
					B2 = N2;
				}
			}
			A[r][c] = (A1 + A2) % mod;
			B[r][c] = (B1 + B2) % mod;
			C[r][c] = (C1 + C2) % mod;
			N[r][c] = (N1 + N2) % mod;
		}
	}
	int ans = (A[h][w] + C[h][w]) % mod;
	Cout(ans);
	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 70060
final_rank: 3

code_snippet: // AOJ #2973 Route Calculator Returns
// 2025.2.16
 
#include <bits/stdc++.h>
using namespace std;
using ll = long long; 

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cins(char t[]) { // 文字列の入力　スペース以下の文字で入力終了
    char *s = t;
	do *s = gc();
	while (*s++ > ' ');
	*(s-1) = 0;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int NMAX = 2005;
ll h, w, mod;
char ch[NMAX][NMAX];
ll A[NMAX][NMAX], B[NMAX][NMAX], C[NMAX][NMAX], N[NMAX][NMAX];

int main(void) {
	h = Cin(), w = Cin(), mod = Cin();
	for(int r = 1; r <= h; r++) Cins(ch[r]+1);
	
	A[1][1] = 0, B[1][1] = 1, C[1][1] = ch[1][1]-'0', N[1][1] = 1;
    for(int r = 1; r <= h; r++){
    	for(int c = 1; c <= w; c++){
			if(c == 1 && r == 1) continue;
            char cc = ch[r][c];

			ll A1 = A[r][c-1], A2 = A[r-1][c];
			ll B1 = B[r][c-1], B2 = B[r-1][c];
			ll C1 = C[r][c-1], C2 = C[r-1][c];
			ll N1 = N[r-1][c], N2 = N[r][c-1];
			

			if(isdigit(cc)) {
				C1 = (C1 * 10) % mod;
				C2 = (C2 * 10) % mod;
				C1 = (C1 + B1 * (cc & 0xf)) % mod;
				C2 = (C2 + B2 * (cc & 0xf)) % mod;
			} else {
				if(cc == '*' || cc == '+'){
					B1 = C1;
					B2 = C2;
					C1 = C2 = 0;
				}
				if(cc == '+'){
					A1 = (A1 + B1) % mod;
					A2 = (A2 + B2) % mod;
					B1 = N1;
					B2 = N2;
				}
			}
			A[r][c] = (A1 + A2) % mod;
			B[r][c] = (B1 + B2) % mod;
			C[r][c] = (C1 + C2) % mod;
			N[r][c] = (N1 + N2) % mod;
		}
	}
	ll ans = A[h][w] + C[h][w];
	Cout(ans % mod);
	return 0;
}
accuracy: 1
time_ms: 180
memory_kb: 132928
final_rank: 6

code_snippet: // AOJ #2973 Route Calculator Returns
// 2025.2.16
 
#include <bits/stdc++.h>
using namespace std;
using ll = long long; 

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int NMAX = 2005;
ll h, w, mod;
char ch[NMAX][NMAX];
ll A[NMAX][NMAX], B[NMAX][NMAX], C[NMAX][NMAX], N[NMAX][NMAX];

int main(void) {
	h = Cin(), w = Cin(), mod = Cin();
	for(int r = 1; r <= h; r++){
		for(int c = 1; c <= w; c++) ch[c][r] = gc();
        gc();
	}
	
	A[1][1] = 0, B[1][1] = 1, C[1][1] = ch[1][1]-'0', N[1][1] = 1;
	for(int c = 1; c <= w; c++){
		for(int r = 1; r <= h; r++){
			if(c == 1 && r == 1) continue;
            char cc = ch[c][r];

			ll A1 = A[c-1][r], A2 = A[c][r-1];
			ll B1 = B[c-1][r], B2 = B[c][r-1];
			ll C1 = C[c-1][r], C2 = C[c][r-1];
			ll N1 = N[c][r-1], N2 = N[c-1][r];
			

			if(isdigit(cc)) {
				C1 = (C1 * 10) % mod;
				C2 = (C2 * 10) % mod;
				C1 = (C1 + B1 * (cc & 0xf)) % mod;
				C2 = (C2 + B2 * (cc & 0xf)) % mod;
			} else {
				if(cc == '*' || cc == '+'){
					B1 = C1;
					B2 = C2;
					C1 = C2 = 0;
				}
				if(cc == '+'){
					A1 = (A1 + B1) % mod;
					A2 = (A2 + B2) % mod;
					B1 = N1;
					B2 = N2;
				}
			}
			A[c][r] = (A1 + A2) % mod;
			B[c][r] = (B1 + B2) % mod;
			C[c][r] = (C1 + C2) % mod;
			N[c][r] = (N1 + N2) % mod;
		}
	}
	ll ans = A[w][h] + C[w][h];
	Cout(ans % mod);
	return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 132904
final_rank: 7

code_snippet: // AOJ #2973 Route Calculator Returns
// 2025.2.16

#include <bits/stdc++.h>
using namespace std;
using ll = long long; 
 
ll MOD;
int H, W;
 
inline int idx(int i, int j) { return i * (W + 1) + j; }

struct AggDigit { ll S, T, U, cnt; };
struct AggOpPlus { ll sum, cnt; };
struct AggOpStar { ll sumA, sumR, cnt; };
 
inline ll safeMod(ll a) {
    a %= MOD;
    if(a < 0) a += MOD;
    return a;
}
 
inline ll modAdd(ll a, ll b) {
    return safeMod(a + b);
}
 
inline ll modMul(ll a, ll b) {
    return safeMod(a * b);
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    cin >> H >> W >> MOD;
    vector<string> grid(H);
    for (int i = 0; i < H; i++) cin >> grid[i];
 
    vector<AggDigit> dpDigit((H+1) * (W+1), {0,0,0,0});
    vector<AggOpPlus> dpOpPlus((H+1) * (W+1), {0,0});
    vector<AggOpStar> dpOpStar((H+1) * (W+1), {0,0,0});
 
    int d = grid[0][0] - '0';
    {
        int id = idx(1,1);
        dpDigit[id].S = safeMod(d);
        dpDigit[id].T = safeMod(d);
        dpDigit[id].U = 1;
        dpDigit[id].cnt = 1;
    }
 
    for (int i = 1; i <= H; i++){
        for (int j = 1; j <= W; j++){
            int pos = idx(i, j);
            char c = grid[i-1][j-1];
            for (int dxy = 0; dxy < 2; dxy++){
                int ni = i, nj = j;
                if(dxy == 0) nj = j+1; else ni = i+1;
                if(ni > H || nj > W) continue;
                int npos = idx(ni, nj);
                char nc = grid[ni-1][nj-1];
 
                if( ('0' <= c && c <= '9') ) {
                    AggDigit cur = dpDigit[pos];
                    if(cur.cnt == 0) continue;
 
                    if( '0' <= nc && nc <= '9' ) {
                        int nd = nc - '0';
                        AggDigit nxt;
                        nxt.cnt = cur.cnt;
                        nxt.T = modAdd(modMul(10, cur.T), modMul(cur.U, nd));
                        nxt.S = modAdd(cur.S, modAdd(modMul(10, cur.T) - cur.T, modMul(cur.U, nd)));
                        nxt.S = safeMod(nxt.S);
                        nxt.U = cur.U;
                        dpDigit[npos].S = modAdd(dpDigit[npos].S, nxt.S);
                        dpDigit[npos].T = modAdd(dpDigit[npos].T, nxt.T);
                        dpDigit[npos].U = modAdd(dpDigit[npos].U, nxt.U);
                        dpDigit[npos].cnt = modAdd(dpDigit[npos].cnt, nxt.cnt);
                    } else {
                        if(nc == '+'){
                            AggOpPlus nxt;
                            nxt.sum = cur.S;
                            nxt.cnt = cur.cnt;
                            dpOpPlus[npos].sum = modAdd(dpOpPlus[npos].sum, nxt.sum);
                            dpOpPlus[npos].cnt = modAdd(dpOpPlus[npos].cnt, nxt.cnt);
                        } else if(nc == '*'){
                            AggOpStar nxt;
                            nxt.sumA = safeMod(cur.S - cur.T);
                            nxt.sumR = cur.T;
                            nxt.cnt = cur.cnt;
                            dpOpStar[npos].sumA = modAdd(dpOpStar[npos].sumA, nxt.sumA);
                            dpOpStar[npos].sumR = modAdd(dpOpStar[npos].sumR, nxt.sumR);
                            dpOpStar[npos].cnt = modAdd(dpOpStar[npos].cnt, nxt.cnt);
                        }
                    }
                } else {
                    if(c == '+'){
                        AggOpPlus cur = dpOpPlus[pos];
                        if(cur.cnt == 0) continue;
                        if('0' <= nc && nc <= '9'){
                            int nd = nc - '0';
                            AggDigit nxt;
                            nxt.cnt = cur.cnt;
                            nxt.S = modAdd(cur.sum, modMul(nd, cur.cnt));
                            nxt.T = modMul(nd, cur.cnt);
                            nxt.U = cur.cnt;
                            dpDigit[npos].S = modAdd(dpDigit[npos].S, nxt.S);
                            dpDigit[npos].T = modAdd(dpDigit[npos].T, nxt.T);
                            dpDigit[npos].U = modAdd(dpDigit[npos].U, nxt.U);
                            dpDigit[npos].cnt = modAdd(dpDigit[npos].cnt, nxt.cnt);
                        }
                    } else if(c == '*'){
                        AggOpStar cur = dpOpStar[pos];
                        if(cur.cnt == 0) continue;
                        if('0' <= nc && nc <= '9'){
                            int nd = nc - '0';
                            AggDigit nxt;
                            nxt.cnt = cur.cnt;
                            nxt.S = modAdd(cur.sumA, modMul(nd, cur.sumR));
                            nxt.T = modMul(nd, cur.sumR);
                            nxt.U = cur.sumR;
                            dpDigit[npos].S = modAdd(dpDigit[npos].S, nxt.S);
                            dpDigit[npos].T = modAdd(dpDigit[npos].T, nxt.T);
                            dpDigit[npos].U = modAdd(dpDigit[npos].U, nxt.U);
                            dpDigit[npos].cnt = modAdd(dpDigit[npos].cnt, nxt.cnt);
                        }
                    }
                }
            }
        }
    }
    ll ans = safeMod(dpDigit[idx(H, W)].S);
    cout << ans << endl;
    return 0;
}
accuracy: 0.25
time_ms: 480
memory_kb: 267600
final_rank: 16

code_snippet: // AOJ #2973 Route Calculator Returns
// 2025.2.16

#include <bits/stdc++.h>
using namespace std;
using ll = long long; 
 
ll MOD;
 
struct AggDigit { ll S, T, U, cnt; };
struct AggOpPlus { ll sum, cnt; };
struct AggOpStar { ll sumA, sumR, cnt; };
 
inline ll modMul(ll a, ll b) {
    return ( (a % MOD) * (b % MOD) ) % MOD;
}
 
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int H, W;
    cin >> H >> W >> MOD;
    vector<string> grid(H);
    for (int i = 0; i < H; i++) cin >> grid[i];
 
    vector<vector<AggDigit>> dpDigit(H+1, vector<AggDigit>(W+1, {0,0,0,0}));
    vector<vector<AggOpPlus>> dpOpPlus(H+1, vector<AggOpPlus>(W+1, {0,0}));
    vector<vector<AggOpStar>> dpOpStar(H+1, vector<AggOpStar>(W+1, {0,0,0}));
 
    auto addDigit = [&](int i, int j, const AggDigit &state) {
        dpDigit[i][j].S = (dpDigit[i][j].S + state.S) % MOD;
        dpDigit[i][j].T = (dpDigit[i][j].T + state.T) % MOD;
        dpDigit[i][j].U = (dpDigit[i][j].U + state.U) % MOD;
        dpDigit[i][j].cnt += state.cnt;
    };
    auto addOpPlus = [&](int i, int j, const AggOpPlus &state) {
        dpOpPlus[i][j].sum = (dpOpPlus[i][j].sum + state.sum) % MOD;
        dpOpPlus[i][j].cnt += state.cnt;
    };
    auto addOpStar = [&](int i, int j, const AggOpStar &state) {
        dpOpStar[i][j].sumA = (dpOpStar[i][j].sumA + state.sumA) % MOD;
        dpOpStar[i][j].sumR = (dpOpStar[i][j].sumR + state.sumR) % MOD;
        dpOpStar[i][j].cnt += state.cnt;
    };
 
    int d = grid[0][0] - '0';
    dpDigit[1][1] = { (ll)d % MOD, (ll)d % MOD, 1, 1};
 
    for (int i = 1; i <= H; i++){
        for (int j = 1; j <= W; j++){
            char c = grid[i-1][j-1];
            if(isdigit(c)){
                AggDigit curState = dpDigit[i][j];
                if(curState.cnt == 0) continue;
 
                for (int k = 0; k < 2; k++){
                    int ni = i, nj = j;
                    if(k==0) nj = j+1; else ni = i+1;
                    if(ni > H || nj > W) continue;
 
                    char nc = grid[ni-1][nj-1];
                    if(isdigit(nc)){
                        int nd = nc - '0';
                        AggDigit newState;
                        newState.cnt = curState.cnt;
                        newState.S = ( curState.S + modMul(9, curState.T) + modMul(nd, curState.U) ) % MOD;
                        newState.T = ( modMul(10, curState.T) + modMul(nd, curState.U) ) % MOD;
                        newState.U = curState.U % MOD;
                        addDigit(ni, nj, newState);
                    } else {
                        if(nc == '+'){
                            AggOpPlus newOp;
                            newOp.sum = curState.S % MOD;
                            newOp.cnt = curState.cnt;
                            addOpPlus(ni, nj, newOp);
                        } else if(nc == '*'){
                            AggOpStar newOp;
                            ll diff = (curState.S - curState.T) % MOD;
                            if(diff < 0) diff += MOD;
                            newOp.sumA = diff;
                            newOp.sumR = curState.T % MOD;
                            newOp.cnt = curState.cnt;
                            addOpStar(ni, nj, newOp);
                        }
                    }
                }
            } else {
                if(c == '+'){
                    AggOpPlus curState = dpOpPlus[i][j];
                    if(curState.cnt == 0) continue;
                    for (int k = 0; k < 2; k++){
                        int ni = i, nj = j;
                        if(k==0) nj = j+1; else ni = i+1;
                        if(ni > H || nj > W) continue;
                        char nc = grid[ni-1][nj-1];
                        if(isdigit(nc)){
                            int nd = nc - '0';
                            AggDigit newState;
                            newState.cnt = curState.cnt;
                            newState.S = ( curState.sum + modMul(nd, curState.cnt) ) % MOD;
                            newState.T = modMul(nd, curState.cnt) % MOD;
                            newState.U = curState.cnt % MOD;
                            addDigit(ni, nj, newState);
                        }
                    }
                } else if(c == '*'){
                    AggOpStar curState = dpOpStar[i][j];
                    if(curState.cnt == 0) continue;
                    for (int k = 0; k < 2; k++){
                        int ni = i, nj = j;
                        if(k==0) nj = j+1; else ni = i+1;
                        if(ni > H || nj > W) continue;
                        char nc = grid[ni-1][nj-1];
                        if(isdigit(nc)){
                            int nd = nc - '0';
                            AggDigit newState;
                            newState.cnt = curState.cnt;
                            newState.S = ( curState.sumA + modMul(nd, curState.sumR) ) % MOD;
                            newState.T = modMul(nd, curState.sumR) % MOD;
                            newState.U = curState.sumR % MOD;
                            addDigit(ni, nj, newState);
                        }
                    }
                }
            }
        }
    }
 
    ll ans = dpDigit[H][W].S % MOD;
    cout << ans << endl;
    return 0;
}
accuracy: 0.15
time_ms: 520
memory_kb: 213604
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

struct Data {
    ll X, Y, Z, W;
    Data(ll x, ll y, ll z, ll w) : X(x), Y(y), Z(z), W(w) {}
};

ll MOD;

void chAdd(Data& D, Data E) {
    D.X += E.X;
    D.X %= MOD;
    D.Y += E.Y;
    D.Y %= MOD;
    D.Z += E.Z;
    D.Z %= MOD;
    D.W += E.W;
    D.W %= MOD;
}

Data Calc(Data D, char C) {
    if (isdigit(C)) {
        ll A = C - '0';
        return Data(D.X, D.Y, (D.Z * 10 + D.Y * A) % MOD, D.W);
    }
    else if (C == '+') {
        return Data((D.X + D.Z) % MOD, D.W, 0, D.W);
    }
    else {
        return Data(D.X, D.Z, 0, D.W);
    }
}

int main() {
    int N, M;
    cin >> N >> M >> MOD;
    vector<vector<char>> C(N, vector<char>(M));
    rep(i,0,N) rep(j,0,M) cin >> C[i][j];
    vector DP(N, vector<Data>(M, Data(0,0,0,0)));
    DP[0][0] = Data(0,1,(C[0][0] - '0') % MOD,1);
    rep(i,0,N) {
        rep(j,0,M) {
            if (i != N-1) {
                Data D = Calc(DP[i][j], C[i+1][j]);
                chAdd(DP[i+1][j], D);
            }
            if (j != M-1) {
                Data D = Calc(DP[i][j], C[i][j+1]);
                chAdd(DP[i][j+1], D);
            }
        }
    }
    cout << (DP[N-1][M-1].X + DP[N-1][M-1].Z) % MOD << endl;
}
accuracy: 1
time_ms: 340
memory_kb: 125688
final_rank: 10

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

int main() {
    int H, W, m;
    read(H, W, m);
    vector<string> a(H);
    read(a);

    vector dp(H, vector(W, vector<int>(4)));
    dp[0][0][1] = dp[0][0][3] = 1;
    rep(i, 0, H) rep(j, 0, W) {
        rep(k, 0, 4) {
            if (i) {
                dp[i][j][k] += dp[i - 1][j][k];
                dp[i][j][k] %= m;
            }
            if (j) {
                dp[i][j][k] += dp[i][j - 1][k];
                dp[i][j][k] %= m;
            }
        }
        if (a[i][j] == '+') {
            dp[i][j][0] += dp[i][j][2];
            dp[i][j][0] %= m;
            dp[i][j][1] = dp[i][j][3];
            dp[i][j][2] = 0;
        } else if (a[i][j] == '*') {
            dp[i][j][1] = dp[i][j][2];
            dp[i][j][2] = 0;
        } else {
            dp[i][j][2] = ll(dp[i][j][2]) * 10 % m;
            dp[i][j][2] %= m;
            dp[i][j][2] += ll(dp[i][j][1]) * (a[i][j] - '0') % m;
            dp[i][j][2] %= m;
        }
    }
    int ret = (dp[H - 1][W - 1][0] + dp[H - 1][W - 1][2]) % m;
    print(ret);
    return 0;
}
accuracy: 1
time_ms: 300
memory_kb: 218452
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define ll long long
#define elif else if
#define vi vector<int>
#define vll vector<ll>
#define vvi vector<vi>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, l, r) for (int i = l; i < (r); i++)

int H, W;
ll mod;

bool in_mat(int x, int y)
{
  return 0 <= x && x < H && 0 <= y && y < W;
}

vector<pair<int, int>> dxdy = {{0, 1}, {1, 0}};

int main()
{
  cin >> H >> W >> mod;
  vector<string> S(H);
  rep(i, H) cin >> S[i];

  int n = H + W + 10;
  vector<vll> binom(n, vll(n, 0));
  rep(i, n)
  {
    binom[i][0] = 1;
    rep2(j, 1, i + 1)
    {
      binom[i][j] = (binom[i - 1][j - 1] + binom[i - 1][j]) % mod;
    }
  }

  vector<vector<pair<ll, ll>>> dp(H, vector<pair<ll, ll>>(W, {0, 0}));
  ll ans = 0;
  dp[0][0] = {1, 0};
  rep(x, H) rep(y, W)
  {
    if (S[x][y] == '+')
    {
      ans += dp[x][y].second * binom[(H - 1 - x) + (W - 1 - y)][H - 1 - x];
      ans %= mod;
      dp[x][y] = {binom[x + y][y], 0};
    }
    elif (S[x][y] == '*')
    {
      dp[x][y].first = dp[x][y].second;
      dp[x][y].second = 0;
    }
    else
    {
      ll val = dp[x][y].second * 10 + dp[x][y].first * (S[x][y] - '0');
      dp[x][y].second = val % mod;
    }
    for (auto [dx, dy] : dxdy)
    {
      int nx = x + dx;
      int ny = y + dy;
      if (in_mat(nx, ny))
      {
        dp[nx][ny].first += dp[x][y].first;
        dp[nx][ny].first %= mod;
        dp[nx][ny].second += dp[x][y].second;
        dp[nx][ny].second %= mod;
      }
    }
    // cout<<x<<" "<<y<<":"<<dp[x][y].first<<" "<<dp[x][y].second<<endl;
  }
  ans += dp[H - 1][W - 1].second;
  cout << ans % mod << endl;
}
accuracy: 1
time_ms: 280
memory_kb: 189280
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;

vector<int> dh={-1,0},dw={0,-1};
int main(){
    ll H,W,M;
    cin>>H>>W>>M;
    vector<string> S(H);
    for(int i=0;i<H;i++)cin>>S[i];
    vector<vector<ll>> SM(H,vector<ll>(W,0));
    auto PR=SM;
    auto NUM=SM;
    auto NN=SM;
    PR[0][0]=NN[0][0]=1;
    NUM[0][0]=S[0][0]-'0';
    for(int h=0;h<H;h++){
        for(int w=0;w<W;w++){
            char c=S[h][w];
            for(int d=0;d<2;d++){
                int ph=h+dh[d],pw=w+dw[d];
                if(ph<0||pw<0)continue;
                NN[h][w]+=NN[ph][pw];
                SM[h][w]+=SM[ph][pw];
                if(c=='+'){
                    SM[h][w]+=NUM[ph][pw];
                    PR[h][w]+=NN[ph][pw];
                }
                else if(c=='*'){
                    PR[h][w]+=NUM[ph][pw];
                }
                else{
                    PR[h][w]+=PR[ph][pw];
                    NUM[h][w]+=NUM[ph][pw]*10+PR[ph][pw]*(c-'0');
                }
            }
            NN[h][w]%=M;
            SM[h][w]%=M;
            PR[h][w]%=M;
            NUM[h][w]%=M;
        }
    }
    cout<<(SM[H-1][W-1]+NUM[H-1][W-1])%M<<endl;
}
accuracy: 1
time_ms: 180
memory_kb: 129804
final_rank: 5