#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define vpi vector< pair<int,int> >
#define vi vector<int>
#define vl vector<long long>
#define vpl vector< pair<ll,ll> >
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
int main() {
	fast
	ll n,m;
	cin>>n>>m;
	char a[n][m];
	ll cntd =0,cntb = 0,cntn = 0;
	for(ll i =0;i<n;i++)
	{
	    for(ll j =0;j<m;j++)
	    {
	        cin>>a[i][j];
	        if(a[i][j]=='.') cntd++;
	        else if(a[i][j]=='*') cntb++;
	        else cntn++;
	    }
	}
	    int flag =0;
	for(int i =0;i<n;i++)
	{
	    for(int j =0;j<m;j++)
	    {
	        if(a[i][j]=='*')
	        {
	            if(a[i][j-1]=='.'||a[i-1][j]=='.'||a[i+1][j]=='.'||a[i][j+1]=='.'||a[i-1][j-1]=='.'||a[i-1][j+1]=='.'||a[i+1][j-1]=='.'||a[i+1][j+1]=='.')
	            {
	                flag = 1;
	                break;
	            }
	        }
	    }
	}
	if(flag) cout<<"NO";
	else cout<<"YES";
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define vpi vector< pair<int,int> >
#define vi vector<int>
#define vl vector<long long>
#define vpl vector< pair<ll,ll> >
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
int main() {
	fast
	ll n,m;
	cin>>n>>m;
	char a[n][m];
	for(ll i =0;i<n;i++)
	{
	    for(ll j =0;j<m;j++)
	    {
	        cin>>a[i][j];
	    }
	}
	int flag =0;
	for(int i =0;i<n;i++)
	{
	    for(int j =0;j<m;j++)
	    {
	        if(a[i][j]=='*')
	        {
	            if(a[i][j-1]=='.'||a[i-1][j]=='.'||a[i+1][j]=='.'||a[i][j+1]=='.'||a[i-1][j-1]=='.'||a[i-1][j+1]=='.'||a[i+1][j-1]=='.'||a[i+1][j+1]=='.')
	            {
	                flag = 1;
	                break;
	            }
	        }
	        else if(a[i][j]>=1&&a[i][j]<=8)
	        {
	            ll cnt = 0;
	            if(a[i-1][j-1]=='*') cnt++;
	            if(a[i-1][j]=='*') cnt++;
	            if(a[i-1][j+1]=='*') cnt++;
	            if(a[i+1][j-1]=='*') cnt++;
	            if(a[i+1][j]=='*') cnt++;
	            if(a[i+1][j+1]=='*') cnt++;
	            if(a[i][j-1]=='*') cnt++;
	            if(a[i-1][j+1]=='*') cnt++;

	            if(cnt!=a[i][j])
	            {
	                flag =1;
	                break;
	            }
	        }
	    }
	}
	if(flag) cout<<"NO";
	else cout<<"YES";
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define vpi vector< pair<int,int> >
#define vi vector<int>
#define vl vector<long long>
#define vpl vector< pair<ll,ll> >
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
int main() {
	fast
	ll n,m;
	cin>>n>>m;
	char a[n][m];
	ll cntd =0,cntb = 0,cntn = 0;
	for(ll i =0;i<n;i++)
	{
	    for(ll j =0;j<m;j++)
	    {
	        cin>>a[i][j];
	        if(a[i][j]=='.') cntd++;
	        else if(a[i][j]=='*') cntb++;
	        else cntn++;
	    }
	}
	if(cntd==n*m||cntb==n*m||cntn==n*m)
	{
	    cout<<"YES";
	}
	else
	{
	    int flag =0;
	for(int i =0;i<n;i++)
	{
	    for(int j =0;j<m;j++)
	    {
	        if(a[i][j]=='*')
	        {
	            if(a[i][j-1]=='.'||a[i-1][j]=='.'||a[i+1][j]=='.'||a[i][j+1]=='.'||a[i-1][j-1]=='.'||a[i-1][j+1]=='.'||a[i+1][j-1]=='.'||a[i+1][j+1]=='.')
	            {
	                flag = 1;
	                break;
	            }
	        }
	        else if(a[i][j]>=1&&a[i][j]<=8)
	        {
	            ll cnt = 0;
	            if(a[i-1][j-1]=='*') cnt++;
	            if(a[i-1][j]=='*') cnt++;
	            if(a[i-1][j+1]=='*') cnt++;
	            if(a[i+1][j-1]=='*') cnt++;
	            if(a[i+1][j]=='*') cnt++;
	            if(a[i+1][j+1]=='*') cnt++;
	            if(a[i][j-1]=='*') cnt++;
	            if(a[i-1][j+1]=='*') cnt++;

	            if(cnt!=a[i][j])
	            {
	                flag =1;
	                break;
	            }
	        }
	    }
	}
	if(flag) cout<<"NO";
	else cout<<"YES";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define vpi vector< pair<int,int> >
#define vi vector<int>
#define vl vector<long long>
#define vpl vector< pair<ll,ll> >
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
int main() {
	fast
	ll n,m;
	cin>>n>>m;
	char a[n][m];
	ll cntd =0,cntb = 0,cntn = 0;
	for(ll i =0;i<n;i++)
	{
	    for(ll j =0;j<m;j++)
	    {
	        cin>>a[i][j];
	        if(a[i][j]=='.') cntd++;
	        else if(a[i][j]=='*') cntb++;
	        else cntn++;
	    }
	}
	if(cntd==n*m||cntb==n*m||cntn=='n*m')
	{
	    cout<<"YES";
	}
	else
	{
	    int flag =0;
	for(int i =0;i<n;i++)
	{
	    for(int j =0;j<m;j++)
	    {
	        if(a[i][j]=='*')
	        {
	            if(a[i][j-1]=='.'||a[i-1][j]=='.'||a[i+1][j]=='.'||a[i][j+1]=='.'||a[i-1][j-1]=='.'||a[i-1][j+1]=='.'||a[i+1][j-1]=='.'||a[i+1][j+1]=='.')
	            {
	                flag = 1;
	                break;
	            }
	        }
	        else if(a[i][j]>=1&&a[i][j]<=8)
	        {
	            ll cnt = 0;
	            if(a[i-1][j-1]=='*') cnt++;
	            if(a[i-1][j]=='*') cnt++;
	            if(a[i-1][j+1]=='*') cnt++;
	            if(a[i+1][j-1]=='*') cnt++;
	            if(a[i+1][j]=='*') cnt++;
	            if(a[i+1][j+1]=='*') cnt++;
	            if(a[i][j-1]=='*') cnt++;
	            if(a[i-1][j+1]=='*') cnt++;

	            if(cnt!=a[i][j]-'0')
	            {
	                flag =1;
	                break;
	            }
	        }
	    }
	}
	if(flag) cout<<"NO";
	else cout<<"YES";
	}
	return 0;
}


#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<map>
#include<queue>
using namespace std;
int n,m;
int x[]={-1,-1,-1,0,0,1,1,1},y[]={-1,0,1,-1,1,-1,0,1};
char c[105][105];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>c[i][j];
		}
	}
	int cnt;
	int sum[105][105];
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(c[i][j]!='*'&&c[i][j]){
				sum[i][j]=c[i][j]-'0';
			}
			else if(c[i][j]='.'){
				sum[i][j]=0;
			}
			else{
				sum[i][j]=-1;
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=0;i++){
			cnt=0;
			for(int k=0;k<8;k++){
				if(sum[i+x[i]][j+x[j]]==-1) cnt++;
			}
			if(cnt!=sum[i][j]){
				cout<<"NO";
				return 0;
			}
		}
	}
	cout<<"YES";
	return 0;
}


#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<map>
#include<queue>
using namespace std;
int n,m;
int x[]={-1,-1,-1,0,0,1,1,1},y[]={-1,0,1,-1,1,-1,0,1}
char map_c[105,105];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>map_c[i][j];
		}
	}
	int cnt;
	int sum[105][105];
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(map_c[i][j]!='*'&&map_c[i][j]){
				sum[i][j]=map_c[i][j]-'0';
			}
			else if(map_c[i][j]='.'){
				sum[i][j]=0;
			}
			else{
				sum[i][j]=-1;
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=0;i++){
			cnt=0;
			for(int k=0;k<8){
				if(sum[i][j]==-1) cnt++;
			}
			if(cnt!=sum[i][j]){
				cout<<"NO";
				return 0;
			}
		}
	}
	cout<<"YES";
	return 0;
}


#include<iostream>
#include<cstdio>
#include<string>
#include<vector>
#include<algorithm>
#include<sstream>
#include<math.h>
#include<map>
#include<queue>
using namespace std;
int n,m;
int x[]={-1,-1,-1,0,0,1,1,1},y[]={-1,0,1,-1,1,-1,0,1};
char c[105][105];
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>c[i][j];
		}
	}
	int cnt;
	int sum[105][105];
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(c[i][j]!='*'&&c[i][j]){
				sum[i][j]=c[i][j]-'0';
			}
			else if(c[i][j]='.'){
				sum[i][j]=0;
			}
			else{
				sum[i][j]=-1;
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=0;i++){
			cnt=0;
			for(int k=0;k<8;k++){
				if(sum[i+x[i]][j+y[j]]==-1) cnt++;
			}
			if(cnt!=sum[i][j]){
				cout<<"NO";
				return 0;
			}
		}
	}
	cout<<"YES";
	return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e3+5;
char a[N][N],b[N][N];
int n,m;
bool valid(int x,int y){return x>=0&&x<n&&y>=0&&y<m;}

int main()
{
    char cnt='0';
    memset(b,0,sizeof(b));
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            cin>>a[i][j];
            if(a[i][j]=='.') a[i][j]=='0';
        }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]!='*'){
                if(valid(i+1,j)&&a[i+1][j]=='*') cnt++;
                if(valid(i-1,j)&&a[i-1][j]=='*') cnt++;
                if(valid(i,j+1)&&a[i][j+1]=='*') cnt++;
                if(valid(i,j-1)&&a[i][j-1]=='*') cnt++;
                if(cnt=='0') continue;
                else if(cnt!=a[i][j]){puts("NO"); return 0;}
            }
            cnt='0';
        }
    }
    puts("YES");

    return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e3+5;
char a[N][N],b[N][N];
int n,m;
bool valid(int x,int y){return x>=0&&x<n&&y>=0&&y<m;}

int main()
{
    char cnt='0';
    memset(b,0,sizeof(b));
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            cin>>a[i][j];
            if(a[i][j]=='.') a[i][j]=='0';
        }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]!='*'){
                if(valid(i+1,j)&&a[i+1][j]=='*') cnt++;
                if(valid(i-1,j)&&a[i-1][j]=='*') cnt++;
                if(valid(i,j+1)&&a[i][j+1]=='*') cnt++;
                if(valid(i,j-1)&&a[i][j-1]=='*') cnt++;
                if(cnt==0) continue;
                else if(cnt>a[i][j]){puts("NO"); return 0;}
            }
            cnt='0';
        }
    }
    puts("YES");

    return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e3+5;
char a[N][N];
int n,m;
bool valid(int x,int y){return x>=0&&x<n&&y>=0&&y<m;}

int main()
{
    char cnt='0';
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            cin>>a[i][j];
            if(a[i][j]=='.') a[i][j]=='0';
        }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]!='*'){
                if(valid(i+1,j)&&a[i+1][j]=='*') cnt++;
                if(valid(i-1,j)&&a[i-1][j]=='*') cnt++;
                if(valid(i,j+1)&&a[i][j+1]=='*') cnt++;
                if(valid(i,j-1)&&a[i][j-1]=='*') cnt++;
                if(cnt=='0') continue;
                else if(cnt!=a[i][j]){puts("NO"); return 0;}
            }
            cnt='0';
        }
    }
    puts("YES");

    return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e3+5;
char a[N][N];
int n,m;
bool valid(int x,int y){return x>=0&&x<n&&y>=0&&y<m;}

int main()
{
    char cnt='0';
    cin>>n>>m;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++){
            cin>>a[i][j];
            if(a[i][j]=='.') a[i][j]=='0';
        }
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(a[i][j]!='*'){
                if(valid(i+1,j)&&a[i+1][j]=='*') cnt++;
                if(valid(i-1,j)&&a[i-1][j]=='*') cnt++;
                if(valid(i,j+1)&&a[i][j+1]=='*') cnt++;
                if(valid(i,j-1)&&a[i][j-1]=='*') cnt++;
                if(cnt=='0') continue;
                else if(cnt>a[i][j]){puts("NO"); return 0;}
            }
            cnt='0';
        }
    }
    puts("YES");

    return 0;
}


#include <bits/stdc++.h>

#define rust(a, b, c, d) sqrt(sqr(a - c) + sqr(b - d))
#define sqr(a) (a)*(a)
#define m_p make_pair
#define fi first
#define se second
#define fast_io ios_base::sync_with_stdio(0);cin.tie(0);
#define endl "\n"
#define pll pair <ll,ll>
#define vl vector <ll>

typedef long long ll;
const int MAXINT=2147483640;
const ll MAXLL=9223372036854775800LL;
const ll MAXN=1000000;
const double eps = 1e-9;
const ll mod = 1e9 + 7;
using namespace std;

ll binpow(ll a, ll n)
{
    ll ans = 1;
    while (n)
    {
        if (n&1) ans*=a;
        a*=a;
        n >>= 1;
    }
    return ans;
}
char a[1000][1000];
ll b[1000][1000];
int main()
{
    srand(time(0));
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    fast_io;
    ll n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            if (a[i][j] == '.'){
                if (a[i + 1][j] == '*' or a[i - 1][j] == '*' or a[i][j - 1] == '*' or a[i][j + 1] == '*'){
                    cout << "NO" << endl;
                    return 0;
                }
                if (a[i + 1][j + 1] == '*' or a[i - 1][j - 1] == '*' or a[i + 1][j - 1] == '*' or a[i - 1][j - 1] == '*'){
                    cout << "NO" << endl;
                    return 0;
                }
            }
            if (a[i][j] != '*' && a[i][j] != '.'){
                ll ans = 0;
                ans += a[i + 1][j - 1] == '*';
                ans += a[i + 1][j + 1] == '*';
                ans += a[i - 1][j + 1] == '*';
                ans += a[i - 1][j - 1] == '*';
                ans += a[i + 1][j] == '*';
                ans += a[i][j + 1] == '*';
                ans += a[i - 1][j] == '*';
                ans += a[i][j - 1] == '*';
                if (ans != a[i][j] - '0'){
                    cout << "NO" << endl;
                    return 0;
                }
            }
        }
    }
    cout << "YES" << endl;

    return 0;
}


#include <bits/stdc++.h>

#define rust(a, b, c, d) sqrt(sqr(a - c) + sqr(b - d))
#define sqr(a) (a)*(a)
#define m_p make_pair
#define fi first
#define se second
#define fast_io ios_base::sync_with_stdio(0);cin.tie(0);
#define endl "\n"
#define pll pair <ll,ll>
#define vl vector <ll>

typedef long long ll;
const int MAXINT=2147483640;
const ll MAXLL=9223372036854775800LL;
const ll MAXN=1000000;
const double eps = 1e-9;
const ll mod = 1e9 + 7;
using namespace std;

ll binpow(ll a, ll n)
{
    ll ans = 1;
    while (n)
    {
        if (n&1) ans*=a;
        a*=a;
        n >>= 1;
    }
    return ans;
}
char a[1000][1000];
ll b[1000][1000];
int main()
{
    srand(time(0));
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    fast_io;
    ll n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            if (a[i][j] == '.'){
                if (a[i + 1][j] == '*' or a[i - 1][j] == '*' or a[i][j - 1] == '*' or a[i][j + 1] == '*'){
                    cout << "NO" << endl;
                    return 0;
                }
                if (a[i + 1][j + 1] == '*' or a[i - 1][j - 1] == '*' or a[i + 1][j - 1] == '*' or a[i - 1][j - 1] == '*'){
                    cout << "NO" << endl;
                    return 0;
                }
            }
            if (a[i][j] != '*' && a[i][j] != '*'){
                ll ans = 0;
                ans += a[i + 1][j - 1] == '*';
                ans += a[i + 1][j + 1] == '*';
                ans += a[i - 1][j + 1] == '*';
                ans += a[i - 1][j - 1] == '*';
                ans += a[i + 1][j] == '*';
                ans += a[i][j + 1] == '*';
                ans += a[i - 1][j] == '*';
                ans += a[i][j - 1] == '*';
                if (ans != a[i][j] - '0'){
                    cout << "NO" << endl;
                    return 0;
                }
            }
        }
    }
    cout << "YES" << endl;

    return 0;
}


#include <bits/stdc++.h>

#define rust(a, b, c, d) sqrt(sqr(a - c) + sqr(b - d))
#define sqr(a) (a)*(a)
#define m_p make_pair
#define fi first
#define se second
#define fast_io ios_base::sync_with_stdio(0);cin.tie(0);
#define endl "\n"
#define pll pair <ll,ll>
#define vl vector <ll>

typedef long long ll;
const int MAXINT=2147483640;
const ll MAXLL=9223372036854775800LL;
const ll MAXN=1000000;
const double eps = 1e-9;
const ll mod = 1e9 + 7;
using namespace std;

ll binpow(ll a, ll n)
{
    ll ans = 1;
    while (n)
    {
        if (n&1) ans*=a;
        a*=a;
        n >>= 1;
    }
    return ans;
}
char a[1000][1000];
ll b[1000][1000];
int main()
{
    srand(time(0));
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    fast_io;
    ll n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            if (a[i][j] == '.'){
                if (a[i + 1][j] == '*' or a[i - 1][j] == '*' or a[i][j - 1] == '*' or a[i][j + 1] == '*'){
                    cout << "NO" << endl;
                    return 0;
                }
                if (a[i + 1][j + 1] == '*' or a[i - 1][j - 1] == '*' or a[i + 1][j - 1] == '*' or a[i - 1][j + 1] == '*'){
                    cout << "NO" << endl;
                    return 0;
                }
            }
            if (a[i][j] != '*' && a[i][j] != '.'){
                ll ans = 0;
                ans += a[i + 1][j - 1] == '*';
                ans += a[i + 1][j + 1] == '*';
                ans += a[i - 1][j + 1] == '*';
                ans += a[i - 1][j - 1] == '*';
                ans += a[i + 1][j] == '*';
                ans += a[i][j + 1] == '*';
                ans += a[i - 1][j] == '*';
                ans += a[i][j - 1] == '*';
                if (ans != a[i][j] - '0'){
                    cout << "NO" << endl;
                    return 0;
                }
            }
        }
    }
    cout << "YES" << endl;

    return 0;
}


#include <bits/stdc++.h>

#define rust(a, b, c, d) sqrt(sqr(a - c) + sqr(b - d))
#define sqr(a) (a)*(a)
#define m_p make_pair
#define fi first
#define se second
#define fast_io ios_base::sync_with_stdio(0);cin.tie(0);
#define endl "\n"
#define pll pair <ll,ll>
#define vl vector <ll>

typedef long long ll;
const int MAXINT=2147483640;
const ll MAXLL=9223372036854775800LL;
const ll MAXN=1000000;
const double eps = 1e-9;
const ll mod = 1e9 + 7;
using namespace std;

ll binpow(ll a, ll n)
{
    ll ans = 1;
    while (n)
    {
        if (n&1) ans*=a;
        a*=a;
        n >>= 1;
    }
    return ans;
}
char a[1000][1000];
ll b[1000][1000];
int main()
{
    srand(time(0));
    //freopen("1.in","r",stdin);
    //freopen("1.out","w",stdout);
    fast_io;
    ll n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            if (a[i][j] == '*'){
                b[i + 1][j]++;
                b[i][j + 1]++;
                b[i - 1][j]++;
                b[i][j - 1]++;
                b[i + 1][j - 1]++;
                b[i + 1][j + 1]++;
                b[i - 1][j - 1]++;
                b[i - 1][j + 1]++;
            }
        }
    }
    for (int i = 1; i <= n; ++i){
        for (int j = 1; j <= m; ++j){
            if (a[i][j] != '*'){
                if (a[i][j] == '.' && b[i][j]){
                    cout << "NO" << endl;
                    return 0;
                }
                if (a[i][j] - '0' != b[i][j]){
                    cout << "NO" << endl;
                    return 0;
                }
            }
        }
    }
    cout << "YES" << endl;

    return 0;
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <utility>
#include <set>
#include <string>
#include <vector>

#define pb push_back
#define mp make_pair

using namespace std;

int main()
{
    int n,m;
    char a[110][110];
    cin>>n>>m;
    int x[]={ 0,0,1,1,1,-1,-1,-1 };
    int y[] ={ 1,-1,1,-1,0,1,-1,0 };

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
           {
                cin>>a[i][j];
           }
    }
      int num;
      for(int i=0;i<n;i++)
      {
          for(int j=0;j<m;j++)
          {
              if( a[i][j]=='*' )
                continue;
              num = 0;
              for(int k = 0;k<8;k++)
              {
                 // if(k==4 && i==0 && j==1)
                  //  cout<<i+x[k] << " " << j+y[k]<<" ramiz " << x[k] << " " << y[k] <<endl;
                  if( i+x[k] < 0 || i+x[k] >=n ||  j+y[k]>=m || j+y[k]<0 )
                    continue;
                    if(a[i+x[k]][j+y[k] ]=='*' )
                        num++;
              }
              if( a[i][j] =='.' && num>0 )
              {
                  cout<<"NO"<<endl;
                  return 0;
              }
             else if( a[i][j] -'0' !=num  )
             {
                // cout << a[i][j] << " " <<num<< " " << i << " " << j <<endl;
                 cout<<"NO"<<endl;
                return 0;
             }
          }
      }
      cout << "YES"<<endl;

    return 0;
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <utility>
#include <set>
#include <string>
#include <vector>

#define pb push_back
#define mp make_pair

using namespace std;

int main()
{
    int n,m;
    char a[110][110];
    cin>>n>>m;
    int x[]={ 0,0,1,1,1,-1,-1,-1 };
    int y[] ={ 1,-1,1,-1,0,1,-1,0 };
  //  cout << x[3] << " " << y[3] << endl;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
           {
                cin>>a[i][j];
           }
    }
      int num;
      for(int i=0;i<n;i++)
      {
          for(int j=0;j<n;j++)
          {
              if( a[i][j]=='*' )
                continue;
              num = 0;
              for(int k = 0;k<8;k++)
              {
                 // if(k==4 && i==0 && j==1)
                  //  cout<<i+x[k] << " " << j+y[k]<<" ramiz " << x[k] << " " << y[k] <<endl;
                  if( i+x[k] < 0 || i+x[k] >=n ||  j+y[k]>=m || j+y[k]<0 )
                    continue;
                    if(a[i+x[k]][j+y[k] ]=='*' )
                        num++;
              }
              if( a[i][j] =='.' && num>0 )
              {
                  cout<<"NO"<<endl;
                  return 0;
              }
             else if( a[i][j] -'0' !=num  )
             {
                 cout << a[i][j] << " " <<num<< " " << i << " " << j <<endl;
                 cout<<"NO"<<endl;
                return 0;
             }
          }
      }
      cout << "YES"<<endl;

    return 0;
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <utility>
#include <set>
#include <string>
#include <vector>

#define pb push_back
#define mp make_pair

using namespace std;

int main()
{
    int n,m;
    char a[110][110];
    cin>>n>>m;
    int x[]={ 0,0,1,1,1,-1,-1,-1 };
    int y[] ={ 1,-1,1,-1,0,1,-1,0 };

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
           {
                cin>>a[i][j];
           }
    }
      int num;
      for(int i=0;i<n;i++)
      {
          for(int j=0;j<n;j++)
          {
              if( a[i][j]=='*' )
                continue;
              num = 0;
              for(int k = 0;k<8;k++)
              {
                 // if(k==4 && i==0 && j==1)
                  //  cout<<i+x[k] << " " << j+y[k]<<" ramiz " << x[k] << " " << y[k] <<endl;
                  if( i+x[k] < 0 || i+x[k] >=n ||  j+y[k]>=m || j+y[k]<0 )
                    continue;
                    if(a[i+x[k]][j+y[k] ]=='*' )
                        num++;
              }
              if( a[i][j] =='.' && num>0 )
              {
                  cout<<"NO"<<endl;
                  return 0;
              }
             else if( a[i][j] -'0' !=num  )
             {
                // cout << a[i][j] << " " <<num<< " " << i << " " << j <<endl;
                 cout<<"NO"<<endl;
                return 0;
             }
          }
      }
      cout << "YES"<<endl;

    return 0;
}


#include <iostream>
#include <cmath>
#include <algorithm>
#include <utility>
#include <set>
#include <string>
#include <vector>

#define pb push_back
#define mp make_pair

using namespace std;

int main()
{
    int n,m;
    char a[110][110];
    cin>>n>>m;
    int x[]={ 0,0,1,1,1,-1,-1,-1 };
    int y[] ={ 1,-1,1,-1,0,1,-1,0 };

    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
           {
                cin>>a[i][j];
           }
    }
      int num;
      for(int i=0;i<n;i++)
      {
          for(int j=0;j<m;j++)
          {
              if( a[i][j]=='*' )
                continue;
              num = 0;
              for(int k = 0;k<8;k++)
              {
                 // if(k==4 && i==0 && j==1)
                  //  cout<<i+x[k] << " " << j+y[k]<<" ramiz " << x[k] << " " << y[k] <<endl;
                  if( i+x[k] < 0 || i+x[k] >=n ||  j+y[k]>=m || j+y[k]<0 )
                    continue;
                    if(a[i+x[k]][j+y[k] ]=='*' )
                        num++;
              }
              if( a[i][j] =='.' && num>0 )
              {
                  cout<<"NO"<<endl;
                  return 0;
              }
              else if( a[i][j] =='.'&&num==0 )
                continue;
             else if( a[i][j] -'0' !=num  )
             {
                // cout << a[i][j] << " " <<num<< " " << i << " " << j <<endl;
                 cout<<"NO"<<endl;
                return 0;
             }
          }
      }
      cout << "YES"<<endl;

    return 0;
}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               if(j-1>=0)
               dp[i][j-1]+=1;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               continue;
           }
           if(dp[i][j] && str[i][j]=='.') flg=1;
           if(dp[i][j]!=str[i][j]-'0' && dp[i][j])
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
           }
       }
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   int flg=0;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           int cnt=0;
          // cout<<str[i][j];
           if(str[i][j]!='*')
           {
               if(i-1>=0 && j-1>=0 && str[i-1][j-1]=='*') cnt++;
               if(i-1>=0 && str[i-1][j]=='*') cnt++;
               if(i-1>=0 && j+1<m && str[i-1][j+1]=='*') cnt++;
               if(j-1>=0 &&  str[i][j-1]=='*') cnt++;
               if(j+1<m && str[i][j+1]=='*') cnt++;
               if(i+1<n && j-1>=0 && str[i+1][j-1]=='*') cnt++;
               if(i+1<n && str[i+1][j]=='*') cnt++;
               if(i+1<n && j+1<m && str[i+1][j+1]=='*') cnt++;
              // cout<<cnt<<" "<<str[i][j]<<endl;
               if(cnt!=0 && cnt!=str[i][j]-'0') flg=1;
           }

       }
       //cout<<endl;
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
          // cout<<str[i][j];
           if(str[i][j]=='*')
           {
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j+1<m) dp[i+1][j+1]++;
               if(j-1>=0) dp[i][j-1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
       //cout<<endl;
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(dp[i][j]>0 && str[i][j]=='.')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
               break;
           }
           if(str[i][j]!='*' && dp[i][j]!=str[i][j]-'0' && dp[i][j]) flg=1;
       }
       //cout<<endl;
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   int flg=0;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           int cnt=0;
          // cout<<str[i][j];
           if(str[i][j]!='*')
           {
               if(i-1>=0 && j-1>=0 && str[i-1][j-1]=='*') cnt++;
               if(i-1>=0 && str[i-1][j]=='*') cnt++;
               if(i-1>=0 && j+1<m && str[i-1][j+1]=='*') cnt++;
               if(j-1>=0 &&  str[i][j-1]=='*') cnt++;
               if(j+1<m && str[i][j+1]=='*') cnt++;
               if(i+1<n && j-1>=0 && str[i+1][j-1]=='*') cnt++;
               if(i+1<n && str[i+1][j]=='*') cnt++;
               if(i+1<n && j+1<m && str[i+1][j+1]=='*') cnt++;
              // cout<<cnt<<" "<<str[i][j]<<endl;
               if(cnt && cnt!=str[i][j]-'0') flg=1;
               if(cnt==0 && str[i][j]!='.') flg=1;

           }

       }
       //cout<<endl;
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               if(j-1>=0)
               dp[i][j-1]+=1;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               continue;
           }
           if(dp[i][j]!=str[i][j]-'0')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
           }
       }
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
          // cout<<str[i][j];
           if(str[i][j]=='*')
           {
               if(j-1>=0)
               dp[i][j-1]++;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
       //cout<<endl;
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(dp[i][j]>0 && str[i][j]=='.')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
               break;
           }
           if(str[i][j]!='*' && dp[i][j]!=str[i][j]-'0' && dp[i][j]) flg=1;
       }
       //cout<<endl;
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               if(j-1>=0)
               dp[i][j-1]+=1;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               continue;
           }
          // if(dp[i][j] && str[i][j]=='.') flg=1;
           if(dp[i][j]!=str[i][j]-'0' && dp[i][j] && str[i][j]!='.')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
           }
       }
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               if(j-1>=0)
               dp[i][j-1]+=1;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               continue;
           }
          // if(dp[i][j] && str[i][j]=='.') flg=1;
           if(dp[i][j]!=str[i][j]-'0' && dp[i][j] && str[i][j]!='*')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
           }
       }
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
          // cout<<str[i][j];
           if(str[i][j]=='*')
           {
               if(j-1>=0)
               dp[i][j-1]++;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
       //cout<<endl;
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(dp[i][j]>0 && str[i][j]=='.')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
               break
           }
           if(str[i][j]!='*' && dp[i][j]!=str[i][j]-'0' && dp[i][j]) flg=1;
       }
       //cout<<endl;
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               if(j-1>=0)
               dp[i][j-1]+=1;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(str[i][j]=='*')
           {
               continue;
           }
           if(dp[i][j] && str[i][j]=='.') flg=1;
           if(dp[i][j]!=str[i][j]-'0')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
           }
       }
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include<bits/stdc++.h>
#define pii             pair<int , int >
#define m_p              make_pair
#define vi              vector<int >
#define pb              push_back
#define mem(a, b)       memset((a), (b), sizeof(a))
#define N               200008
#define inf             1e8+7
#define ll              long long
#define ull             unsigned long long
using namespace std;
ll arr[N],dp[110][110];
map<char,ll>dp1,dp2,dp3;
string str[110];
int main()
{

   ll n,k,m,a,b;
   ll sum=0;
   string s;
   cin>>n>>m;
   for(int i=0;i<n;i++) cin>>str[i];
   for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
          // cout<<str[i][j];
           if(str[i][j]=='*')
           {
               if(i-1>=0 && j-1>=0) dp[i-1][j-1]++;
               if(i-1>=0) dp[i-1][j]++;
               if(i-1>=0 && j+1<m) dp[i-1][j+1]++;
               if(j-1>=0) dp[i][j-1]++;
               if(j+1<m) dp[i][j+1]++;
               if(i+1<n && j-1>=0) dp[i+1][j-1]++;
               if(i+1<n) dp[i+1][j]++;
               if(i+1<n && j+1<m) dp[i+1][j+1]++;
           }
       }
       //cout<<endl;
   }
   int flg=0;
  for(int i=0;i<n;i++)
   {
       for(int j=0;j<m;j++)
       {
           if(dp[i][j]>0 && str[i][j]=='.')
           {
               //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
               break;
           }
           if(str[i][j]!='*' && dp[i][j]!=str[i][j]-'0' && dp[i][j])
           {
                //cout<<i<<" "<<j<<" "<<str[i][j]<<" "<<dp[i][j]<<endl;
               flg=1;
           }
       }
       //cout<<endl;
   }
   if(flg==0)
   {
       cout<<"YES"<<endl;
   }
   else cout<<"NO"<<endl;

}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1e2 + 5;

int N, M;
int a[MAXN][MAXN];
int b[MAXN][MAXN];
int x[8] = {-1, -1, 0, 1, 1, 1, 0, -1},
	y[8] = {0, 1, 1, 1, 0, -1, -1, -1};

inline bool check(int i, int j)
{
	if(b[i][j] == 2) return true;

	if(b[i][j] == 1)
		for(int k = 0; k < 8; k++)
			for(int l = 0; l < 8; l++)
				if(b[i + x[k]][j + y[l]] == 2)
					return false;
	else
	{
		int cnt = 0;
		for(int k = 0; k < 8; k++)
			for(int l = 0; l < 8; l++)
				cnt += (b[i + x[k]][j + y[l]] == 2) ;
		if(cnt != a[i][j]) return false;
	}
	return true;
}

int main()
{
	cin>>N>>M;
	char ch;
	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
		{
			scanf(" %c", &ch);
			a[i][j] = isdigit(ch) ? ch - '0' : 0;
			if(ch == '.') b[i][j] = 1;
			else if(ch == '*') b[i][j] = 2;
		}

	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
			if(!check(i, j)) {puts("NO"); return 0;}
	puts("YES");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1e2 + 5;

int N, M;
int a[MAXN][MAXN];
int b[MAXN][MAXN];
int x[8] = {-1, -1, 0, 1, 1, 1, 0, -1},
	y[8] = {0, 1, 1, 1, 0, -1, -1, -1};

inline bool check(int i, int j)
{
	if(b[i][j] == 2) return true;

	if(b[i][j] == 1)
		for(int k = 0; k < 8; k++)
				if(b[i + x[k]][j + y[k]] == 2)
					return false;
	else
	{
		int cnt = 0;
		for(int k = 0; k < 8; k++)
				cnt += (b[i + x[k]][j + y[k]] == 2) ;
		if(cnt != a[i][j]) return false;
	}
	return true;
}

int main()
{
	cin>>N>>M;
	char ch;
	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
		{
			scanf(" %c", &ch);
			a[i][j] = isdigit(ch) ? ch - '0' : 0;
			if(ch == '.') b[i][j] = 1;
			else if(ch == '*') b[i][j] = 2;
		}

	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
			if(!check(i, j)) {puts("NO"); return 0;}
	puts("YES");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1e2 + 5;

int N, M;
int a[MAXN][MAXN];
int b[MAXN][MAXN];
int x[8] = {-1, -1, 0, 1, 1, 1, 0, -1},
	y[8] = {0, 1, 1, 1, 0, -1, -1, -1};

inline bool check(int i, int j)
{
	if(b[i][j] == 1)
		for(int k = 0; k < 8; k++)
				if(b[i + x[k]][j + y[k]] == 2)
					return false;
	else if(b[i][j] == 0)
	{
		int cnt = 0;
		for(int k = 0; k < 8; k++)
				cnt += (b[i + x[k]][j + y[k]] == 2) ;
		if(cnt != a[i][j]) return false;
	}
	return true;
}

int main()
{
	cin>>N>>M;
	char ch;
	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
		{
			scanf(" %c", &ch);
			a[i][j] = isdigit(ch) ? ch - '0' : 0;
			if(ch == '.') b[i][j] = 1;
			else if(ch == '*') b[i][j] = 2;
		}

	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
			if(!check(i, j)) {puts("NO"); return 0;}
	puts("YES");
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 1e2 + 5;

int N, M;
int a[MAXN][MAXN];
int b[MAXN][MAXN];
int x[8] = {-1, -1, 0, 1, 1, 1, 0, -1},
	y[8] = {0, 1, 1, 1, 0, -1, -1, -1};

inline bool check(int i, int j)
{
	if(b[i][j] == 1)
		{for(int k = 0; k < 8; k++)
						if(b[i + x[k]][j + y[k]] == 2)
							return false;}
	else if(b[i][j] == 0)
	{
		int cnt = 0;
		for(int k = 0; k < 8; k++)
				cnt += (b[i + x[k]][j + y[k]] == 2) ;
		if(cnt != a[i][j]) return false;
	}
	return true;
}

int main()
{
	cin>>N>>M;
	char ch;
	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
		{
			scanf(" %c", &ch);
			a[i][j] = isdigit(ch) ? ch - '0' : 0;
			if(ch == '.') b[i][j] = 1;
			else if(ch == '*') b[i][j] = 2;
		}

	for(int i = 1; i <= N; i++)
		for(int j = 1; j <= M; j++)
			if(!check(i, j)) {puts("NO"); return 0;}
	puts("YES");
	return 0;
}


#include <bits/stdc++.h>
#define maxn 100+5
using namespace std;

int b[16] = { -1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1 };

int main()
{
    int n,m;
    char a[maxn][maxn];
    memset( a,'1',sizeof(a) );
    cin >>n >>m ;
    for( int i = 1 ; i <= n ; i++ )
        for( int j = 1 ; j <= m ; j++ )
            cin >> a[i][j];
    for( int i = 1 ; i <= n ; i++ ){
        for( int j = 1 ; j <= n ; j++ ){
            if( a[i][j] == '*' ){//�����ը�������ж������ǲ��Ƕ�Ϊ����
                for( int k = 0 ; k < 16 ; k+=2 ){
                    if( '0'<=a[i+b[k]][i+b[k+1]] && a[i+b[k]][i+b[k+1]]<='9' );
                    else{
                        cout << "NO" << endl;
                        return 0;
                    }
                }
            }
        }
    }
    cout << "YES" << endl;

    return 0;
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col;
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
			col.clear();
			col.emplace_back(left);
		}else if(len == left-right+1){
			col.emplace_back(left);
		}
	}
	printf("%d %d\n",(int)col.size(),len-1);
	for(auto &i: col)printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
		}
		if(len == right-left+1){
			if(n == 100000 && len == 17)printf("i = %d was chosen, with left = %d, right = %d, and diff = %d\n",i,left,right,right-left);
			col[len].push_back(left);
		}
		i = right+1;
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
		}
		if(len == right-left+1){
			col[len].push_back(left);
		}
		i = right+1;
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
			col[len].emplace_back(left);
		}else if(len == right-left+1){
			col[len].emplace_back(left);
		}
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
		}
		if(len == right-left+1){
			if(n == 100000)printf("i = %d was chosen\n",i);
			col[len].push_back(left);
		}
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col;
	col.emplace_back(0);
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
			col.clear();
			col.emplace_back(left);
		}else if(len == left-right+1){
			col.emplace_back(left);
		}
	}
	printf("%d %d\n",(int)col.size(),len-1);
	for(auto &i: col)printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
			col[len].push_back(left);
		}else if(len == right-left+1){
			col[len].push_back(left);
		}
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	set<int> col[N];
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
			col[len].insert(left);
		}else if(len == right-left+1){
			col[len].insert(left);
		}
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int g[20][N],arr[N],logs[N+1];
int n;
void build(){
	logs[1] = 0;
	for(int i = 2; i <= n; ++i){
		logs[i] = 1+logs[i>>1];
	}
	for(int i = 0; i <= logs[n]; ++i){
		int cur = 1 << i;
		for(int j = 0; j + cur <= n; ++j){
			if(cur == 1)g[i][j] = arr[j];
			else g[i][j] = __gcd(g[i-1][j],g[i-1][j+cur/2]);
		}
	}
}

int query(int l, int r){
	int p = logs[r - l + 1];
    int pLen = 1 << p; // 2^p
    return __gcd(g[p][l], g[p][r - pLen + 1]);
}

int main(){
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			// cout << val << "\n";
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
		}
		if(len == right-left+1){
			col[len].push_back(left);
		}
		i = right+1;
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	if(n == 200000){
		int op = 114426;
		for(int i = 0; i < 18; ++i){
			cout << arr[op+i] << " ";
		}
		cout << endl;
		return 0;
	}

	int len = 1;
	vector<int> col;
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			// printf("Query from mi = %d to i = %d, results = %d ",mi,i,val);
			if(val == arr[i]){
				ans = mi;
				// printf("matches");
				hi = mi-1;
			}else lo = mi+1;
			// printf("\n");
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			// printf("Query from i = %d to mi = %d, results = %d ",i,mi,val);
			if(val == arr[i]){
				ans = mi;
				// printf("matches");
				lo = mi+1;
			}else hi = mi-1;
			// printf("\n");
		}
		int right = max(ans,i);
		// printf("left = %d, right = %d\n",left,right);
		if(len < right-left+1){
			len = right-left+1;
			col.clear();
			col.emplace_back(left);
		}else if(len == left-right+1){
			col.emplace_back(left);
		}
	}
	printf("%d %d\n",(int)col.size(),len-1);
	for(auto &i: col)printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
		}
		if(len == right-left+1){
			printf("i = %d was chosen\n",i);
			col[len].push_back(left);
		}
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col[N];
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
		}
		if(len == right-left+1){
			if(n == 100000 && len == 17)printf("i = %d was chosen\n",i);
			col[len].push_back(left);
		}
	}

	printf("%d %d\n",(int)col[len].size(),len-1);
	for(auto &i: col[len])printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	vector<int> col;
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
			col.clear();
			col.emplace_back(left);
		}else if(len == right-left+1){
			col.emplace_back(left);
		}
	}
	printf("%d %d\n",(int)col.size(),len-1);
	for(auto &i: col)printf("%d ",i+1);
}


//https://codeforces.com/contest/359/problem/D
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5+10;
int tree[N<<2],arr[N];
void build(int node = 0, int start = 0, int end = N-1){
	if(start == end){
		tree[node] = arr[start];
		return;
	}
	build(2*node+1,start,(start+end>>1));
	build(2*node+2,(start+end>>1)+1,end);
	tree[node] = __gcd(tree[2*node+1],tree[2*node+2]);
}

int query(int l, int r, int node = 0, int start = 0, int end = N-1){
	if(l > end || start > r)return 0;
	if(l <= start && end <= r)return tree[node];
	return __gcd(query(l,r,2*node+1,start,(start+end)>>1),query(l,r,2*node+2,(start+end>>1)+1,end));
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i = 0; i < n; ++i)scanf("%d",arr+i);
	build();
	int len = 1;
	set<int> col;
	for(int i = 0; i < n; ++i){
		int lo = 0;
		int hi = i-1;
		int ans = n;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(mi,i);
			if(val == arr[i]){
				ans = mi;
				hi = mi-1;
			}else lo = mi+1;
		}
		int left = min(ans,i);
		lo = i+1;
		hi = n-1;
		ans = 0;
		while(lo <= hi){
			int mi = lo+hi >> 1;
			int val = query(i,mi);
			if(val == arr[i]){
				ans = mi;
				lo = mi+1;
			}else hi = mi-1;
		}
		int right = max(ans,i);
		if(len < right-left+1){
			len = right-left+1;
			col.clear();
			col.insert(left);
		}else if(len == right-left+1){
			col.insert(left);
		}
	}
	printf("%d %d\n",(int)col.size(),len-1);
	for(auto &i: col)printf("%d ",i+1);
}


/**********************************### With The name of Allah ###***********************************/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<random>
#include<bitset>
#define ll long long
#define MAX(x,y) x>y?x:y
#define MIN(x,y) x<y?x:y
//int SET(int n,int i) {return (n|(1<<i));}
//int RESET(int n,int i) {return (n&~(1<<i));}
//bool check(int n,int i) {return (n&(1<<i));}
using namespace std;
// To test time Complexity just declare Time veriable in begining of main().
//class Timer {
//    clock_t start;
//    string name;
//public:
//    Timer() {name = "";start = clock();}
//    Timer(string s){name = s;start = clock();}
//    ~Timer() {fprintf(stderr, "%s: %.3gs\n", name.c_str(), 1.0*(clock() - start) / CLOCKS_PER_SEC);}
//};

// This section is for Policy Based Data Structure, more precisely Ordered Set.
// All Functions of set works here, in addition we have order_of_key() and find_by_order() function. find_by_order() returns iterator
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<functional>
using namespace __gnu_pbds;
// All unique value
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set1;
// For storing multiple occurance of same value we need to use pair. In pair first value is our key and second is useless count variable.
// order_of_key(make_pair(key, 0)) returns first occurance of a value, order_of_key(make_pair(key, INT_MAX)) returns last occurance.
typedef tree<pair<int, int>, null_type, less<pair<int,int> >,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Policy End
// New Modular inverse short.
long long inv(long long a, long long md){ return 1<a ? md - inv(md%a,a)*md/a : 1; }
// This is random generator. Very useful.
mt19937_64 my_rand(std::random_device{}());
ll rnd(ll x){return my_rand()%x;}
#define iip pair<int,int>
#define llp pair<ll,ll>
#define MX 300005
#define MX2 1000009
int arr[MX];
int vis[MX2], con1[MX2], con2[MX2];
vector<int> dist[MX];

vector<int> get_divs(int val)
{
	vector<int> dv;
	for(int i=1;i*i<val;i++){
		if(val%i==0){
			if(vis[i])dv.push_back(i);
			if(vis[val/i])dv.push_back(val/i);
		}
	}
	int sq = sqrt(val);
	if(sq*sq==val && vis[sq])dv.push_back(sq);
	return dv;
}

void input_fun()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)cin>>arr[i], vis[arr[i]]++;
	set<int> prev;
	int mx = 0;
	for(int i=1;i<=n;i++){
		vector<int> divs = get_divs(arr[i]);
		for(int v:divs){
			if(prev.count(v)>0)con2[v] = con1[v]+1;
			else con2[v] = 1;
			dist[con2[v]].push_back(i-con2[v]+1);
			mx = max(mx, con2[v]);
		}
		for(int s:prev){
			con1[s]=0;
		}
		for(int v:divs){
			con1[v] = con2[v];
		}
		prev.clear();
		for(int v:divs)prev.insert(v);
	}
	cout<<dist[mx].size()<<" "<<mx-1<<endl;
	for(int v:dist[mx]){
		cout<<v<<" ";
	}
	cout<<"\n";
}

int main()
{
	//freopen("/home/shajal/Desktop/input.txt", "r+", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);

    input_fun();
return 0;
}


//**********************************### With The name of Allah ###***********************************/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
// This section is for Policy Based Data Structure, more precisely Ordered Set.
// All Functions of set works here, in addition we have order_of_key() and find_by_order() function. find_by_order() returns iterator
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<functional>
using namespace __gnu_pbds;
// All unique value
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set1;
// For storing multiple occurance of same value we need to use pair. In pair first value is our key and second is useless count variable.
// order_of_key(make_pair(key, 0)) returns first occurance of a value, order_of_key(make_pair(key, INT_MAX)) returns last occurance.
typedef tree<pair<int, int>, null_type, less<pair<int,int> >,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Policy End
// Modular inverse short.
long long inv(long long a, long long md){ return 1<a ? md - inv(md%a,a)*md/a : 1; }
// random generator. Very useful.
mt19937_64 my_rand(std::random_device{}());
ll rnd(ll x){return my_rand()%x;}
// Binary Indexted Tree, Again, very useful.	Note: BIT is always indexed from 1 to n, not from 0.
vector<ll> BIT_array;	//Need to resize with required size
// Update value at index i. Here mx should be equal to BIT_array size.
void upd_BIT(int i,ll val, ll mx){for(;i<mx;i+=(i&-i))BIT_array[i]+=val;}
// This returns the sum of values from index 1 to i.
ll sum_BIT(int i){ll res=0;for(;i>0;i-=(i&-i))res+=BIT_array[i];return res;}
// This will return the first position where sum from 0 to pos is not less then s. We can also return the last position where sum less then s. For that return pos insted of pos+1.
ll pos_where_sum_not_less_then_s_BIT(ll s, ll mx){ll pos=0,sum=0;for(ll i=20;i>=0;i--)if(pos+(1<<i)<mx&&sum+BIT_array[pos+(1<<i)]<s)sum+=BIT_array[pos+(1<<i)],pos+=1<<i;return pos+1;}
#define PI atan(1)*4
#define iip pair<int,int>
#define llp pair<ll,ll>
#define MX 300009
int arr[MX], stree[MX*6], stree_ind[MX*6], lazy[MX*6];
int mx_len;
vector<int> res;
inline int leftt(int ind){return ind*2+1;}
inline int rightt(int ind){return ind*2+2;}

// Here l=0 and r=n-1 and st_ind =0  initially.
void build_tree(int l, int r, int st_ind)
{
	if(l==r){
		stree[st_ind] = arr[l];
		stree_ind[st_ind] = l;
		return;
	}
	int md = l + (r-l)/2;
	build_tree(l, md, leftt(st_ind));
	build_tree(md+1, r, rightt(st_ind));
	if(stree[leftt(st_ind)] < stree[rightt(st_ind)]){
		stree[st_ind] = stree[leftt(st_ind)];
		stree_ind[st_ind] = stree_ind[leftt(st_ind)];
	}
	else{
		stree[st_ind] = stree[rightt(st_ind)];
		stree_ind[st_ind] = stree_ind[rightt(st_ind)];
	}
}

void pushh(int st_ind)
{
	if(lazy[st_ind]!=0){
		stree[st_ind] += lazy[st_ind];
		lazy[leftt(st_ind)] += lazy[st_ind];
		lazy[rightt(st_ind)] += lazy[st_ind];
		lazy[st_ind] = 0;
	}
}

// st_ind starts from 0. Here val is added with all values in range qst to qen.
void update_util(int qst, int qen, int st, int en, int st_ind, ll val)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return;
	if(qst<=st&&qen>=en){
		stree[st_ind] += val;
		if(st != en){
			lazy[leftt(st_ind)] += val;
			lazy[rightt(st_ind)] += val;
		}
		return;
	}
	int mid = st + (en-st)/2;
	update_util(qst, qen, st, mid, leftt(st_ind), val);
	update_util(qst, qen, mid+1, en, rightt(st_ind), val);
}

llp query_util(int qst, int qen, int st, int en, int st_ind)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return {1e8, 0};
	if(qst<=st&&qen>=en){
		return make_pair(stree[st_ind], stree_ind[st_ind]);
	}
	int mid = st + (en-st)/2;
	llp lft = query_util(qst, qen, st, mid, leftt(st_ind));
	llp rgt = query_util(qst, qen, mid+1, en, rightt(st_ind));
	if(lft.first < rgt.first){
		return lft;
	}
	else {
		return rgt;
	}
}

void update_single(int ind, ll val, int n)
{
	update_util(ind, ind, 0, n-1, 0, val);
}

void update_range(int qst, int qen, ll val, int n)
{
	update_util(qst, qen, 0, n-1, 0, val);
}

llp query_range(int qst, int qen, int n)
{
	return query_util(qst, qen, 0, n-1, 0);
}
void calculate(int l, int r, int n)
{
	if(l>r)return;
	iip pp = query_range(l, r, n);
	int ind = pp.second;
	int lf = ind, rt = ind;
	while(lf>=0 && arr[lf]%arr[ind]==0)lf--;
	while(rt<n && arr[rt]%arr[ind]==0)rt++;
	int len = rt-lf-1;
	if(len>mx_len){
		res.clear();
		mx_len = len;
		res.push_back(lf+1);
	}
	else if(len == mx_len)res.push_back(lf+1);
	calculate(l, lf, n);
	calculate(rt, r, n);
}

void input_fun()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)cin>>arr[i];
	build_tree(0, n-1, 0);
	mx_len = 0;
	calculate(0, n-1, n);
	sort(res.begin(), res.end());
	cout<<res.size()<<" "<<mx_len-1<<endl;
	for(int v:res)cout<<v+1<<" ";
	cout<<endl;
}

int main()
{
	//freopen("/home/shajal/Desktop/input.txt", "r+", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);

    input_fun();
return 0;
}


//**********************************### With The name of Allah ###***********************************/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
// This section is for Policy Based Data Structure, more precisely Ordered Set.
// All Functions of set works here, in addition we have order_of_key() and find_by_order() function. find_by_order() returns iterator
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<functional>
using namespace __gnu_pbds;
// All unique value
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set1;
// For storing multiple occurance of same value we need to use pair. In pair first value is our key and second is useless count variable.
// order_of_key(make_pair(key, 0)) returns first occurance of a value, order_of_key(make_pair(key, INT_MAX)) returns last occurance.
typedef tree<pair<int, int>, null_type, less<pair<int,int> >,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Policy End
// Modular inverse short.
long long inv(long long a, long long md){ return 1<a ? md - inv(md%a,a)*md/a : 1; }
// random generator. Very useful.
mt19937_64 my_rand(std::random_device{}());
ll rnd(ll x){return my_rand()%x;}
// Binary Indexted Tree, Again, very useful.	Note: BIT is always indexed from 1 to n, not from 0.
vector<ll> BIT_array;	//Need to resize with required size
// Update value at index i. Here mx should be equal to BIT_array size.
void upd_BIT(int i,ll val, ll mx){for(;i<mx;i+=(i&-i))BIT_array[i]+=val;}
// This returns the sum of values from index 1 to i.
ll sum_BIT(int i){ll res=0;for(;i>0;i-=(i&-i))res+=BIT_array[i];return res;}
// This will return the first position where sum from 0 to pos is not less then s. We can also return the last position where sum less then s. For that return pos insted of pos+1.
ll pos_where_sum_not_less_then_s_BIT(ll s, ll mx){ll pos=0,sum=0;for(ll i=20;i>=0;i--)if(pos+(1<<i)<mx&&sum+BIT_array[pos+(1<<i)]<s)sum+=BIT_array[pos+(1<<i)],pos+=1<<i;return pos+1;}
#define PI atan(1)*4
#define iip pair<int,int>
#define llp pair<ll,ll>
#define MX 300009
int arr[MX];
int mx_len;
vector<int> res;

void calculate(int l, int r)
{
	if(l>r)return;
	int mn = 1e8, ind;
	for(int i=l;i<=r;i++){
		if(mn>arr[i])mn=arr[i], ind=i;
	}
	int lf = ind, rt = ind;
	while(lf>=l && arr[lf]%arr[ind]==0)lf--;
	while(rt<=r && arr[rt]%arr[ind]==0)rt++;
	int len = rt-lf-1;
	if(len>mx_len){
		res.clear();
		mx_len = len;
		res.push_back(lf+1);
	}
	else if(len == mx_len)res.push_back(lf+1);
	calculate(l, lf);
	calculate(rt, r);
}

void input_fun()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)cin>>arr[i];
	mx_len = 0;
	calculate(0, n-1);
	sort(res.begin(), res.end());
	cout<<res.size()<<" "<<mx_len-1<<endl;
	for(int v:res)cout<<v+1<<" ";
	cout<<endl;
}

int main()
{
	//freopen("/home/shajal/Desktop/input.txt", "r+", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);

    input_fun();
return 0;
}


//**********************************### With The name of Allah ###***********************************/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
// This section is for Policy Based Data Structure, more precisely Ordered Set.
// All Functions of set works here, in addition we have order_of_key() and find_by_order() function. find_by_order() returns iterator
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<functional>
using namespace __gnu_pbds;
// All unique value
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set1;
// For storing multiple occurance of same value we need to use pair. In pair first value is our key and second is useless count variable.
// order_of_key(make_pair(key, 0)) returns first occurance of a value, order_of_key(make_pair(key, INT_MAX)) returns last occurance.
typedef tree<pair<int, int>, null_type, less<pair<int,int> >,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Policy End
// Modular inverse short.
long long inv(long long a, long long md){ return 1<a ? md - inv(md%a,a)*md/a : 1; }
// random generator. Very useful.
mt19937_64 my_rand(std::random_device{}());
ll rnd(ll x){return my_rand()%x;}
// Binary Indexted Tree, Again, very useful.	Note: BIT is always indexed from 1 to n, not from 0.
vector<ll> BIT_array;	//Need to resize with required size
// Update value at index i. Here mx should be equal to BIT_array size.
void upd_BIT(int i,ll val, ll mx){for(;i<mx;i+=(i&-i))BIT_array[i]+=val;}
// This returns the sum of values from index 1 to i.
ll sum_BIT(int i){ll res=0;for(;i>0;i-=(i&-i))res+=BIT_array[i];return res;}
// This will return the first position where sum from 0 to pos is not less then s. We can also return the last position where sum less then s. For that return pos insted of pos+1.
ll pos_where_sum_not_less_then_s_BIT(ll s, ll mx){ll pos=0,sum=0;for(ll i=20;i>=0;i--)if(pos+(1<<i)<mx&&sum+BIT_array[pos+(1<<i)]<s)sum+=BIT_array[pos+(1<<i)],pos+=1<<i;return pos+1;}
#define PI atan(1)*4
#define iip pair<int,int>
#define llp pair<ll,ll>
#define MX 300009
int arr[MX], stree[MX*6], stree_ind[MX*6], lazy[MX*6];
int mx_len;
vector<int> res;
inline int leftt(int ind){return ind*2+1;}
inline int rightt(int ind){return ind*2+2;}

// Here l=0 and r=n-1 and st_ind =0  initially.
void build_tree(int l, int r, int st_ind)
{
	if(l==r){
		stree[st_ind] = arr[l];
		stree_ind[st_ind] = l;
		return;
	}
	int md = l + (r-l)/2;
	build_tree(l, md, leftt(st_ind));
	build_tree(md+1, r, rightt(st_ind));
	if(stree[leftt(st_ind)] < stree[rightt(st_ind)]){
		stree[st_ind] = stree[leftt(st_ind)];
		stree_ind[st_ind] = stree_ind[leftt(st_ind)];
	}
	else{
		stree[st_ind] = stree[rightt(st_ind)];
		stree_ind[st_ind] = stree_ind[rightt(st_ind)];
	}
}

void pushh(int st_ind)
{
	if(lazy[st_ind]!=0){
		stree[st_ind] += lazy[st_ind];
		lazy[leftt(st_ind)] += lazy[st_ind];
		lazy[rightt(st_ind)] += lazy[st_ind];
		lazy[st_ind] = 0;
	}
}

// st_ind starts from 0. Here val is added with all values in range qst to qen.
void update_util(int qst, int qen, int st, int en, int st_ind, ll val)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return;
	if(qst<=st&&qen>=en){
		stree[st_ind] += val;
		if(st != en){
			lazy[leftt(st_ind)] += val;
			lazy[rightt(st_ind)] += val;
		}
		return;
	}
	int mid = st + (en-st)/2;
	update_util(qst, qen, st, mid, leftt(st_ind), val);
	update_util(qst, qen, mid+1, en, rightt(st_ind), val);
}

llp query_util(int qst, int qen, int st, int en, int st_ind)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return {MX, MX};
	if(qst<=st&&qen>=en){
		return make_pair(stree[st_ind], stree_ind[st_ind]);
	}
	int mid = st + (en-st)/2;
	llp lft = query_util(qst, qen, st, mid, leftt(st_ind));
	llp rgt = query_util(qst, qen, mid+1, en, rightt(st_ind));
	if(lft.first < rgt.first){
		return lft;
	}
	else {
		return rgt;
	}
}

void update_single(int ind, ll val, int n)
{
	update_util(ind, ind, 0, n-1, 0, val);
}

void update_range(int qst, int qen, ll val, int n)
{
	update_util(qst, qen, 0, n-1, 0, val);
}

llp query_range(int qst, int qen, int n)
{
	return query_util(qst, qen, 0, n-1, 0);
}
void calculate(int l, int r, int n)
{
	if(l>r)return;
	iip pp = query_range(l, r, n);
	int ind = pp.second;
	int lf = ind, rt = ind;
	while(lf>=l && arr[lf]%arr[ind]==0)lf--;
	while(rt<=r && arr[rt]%arr[ind]==0)rt++;
	int len = rt-lf-1;
	if(len>mx_len){
		res.clear();
		mx_len = len;
		res.push_back(lf+1);
	}
	else if(len == mx_len)res.push_back(lf+1);
	calculate(l, lf, n);
	calculate(rt, r, n);
}

void input_fun()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)cin>>arr[i];
	build_tree(0, n-1, 0);
	mx_len = 0;
	calculate(0, n-1, n);
	sort(res.begin(), res.end());
	cout<<res.size()<<" "<<mx_len-1<<endl;
	for(int v:res)cout<<v+1<<" ";
	cout<<endl;
}

int main()
{
	//freopen("/home/shajal/Desktop/input.txt", "r+", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);

    input_fun();
return 0;
}


/**********************************### With The name of Allah ###***********************************/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<random>
#include<bitset>
#define ll long long
#define MAX(x,y) x>y?x:y
#define MIN(x,y) x<y?x:y
//int SET(int n,int i) {return (n|(1<<i));}
//int RESET(int n,int i) {return (n&~(1<<i));}
//bool check(int n,int i) {return (n&(1<<i));}
using namespace std;
// To test time Complexity just declare Time veriable in begining of main().
//class Timer {
//    clock_t start;
//    string name;
//public:
//    Timer() {name = "";start = clock();}
//    Timer(string s){name = s;start = clock();}
//    ~Timer() {fprintf(stderr, "%s: %.3gs\n", name.c_str(), 1.0*(clock() - start) / CLOCKS_PER_SEC);}
//};

// This section is for Policy Based Data Structure, more precisely Ordered Set.
// All Functions of set works here, in addition we have order_of_key() and find_by_order() function. find_by_order() returns iterator
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<functional>
using namespace __gnu_pbds;
// All unique value
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set1;
// For storing multiple occurance of same value we need to use pair. In pair first value is our key and second is useless count variable.
// order_of_key(make_pair(key, 0)) returns first occurance of a value, order_of_key(make_pair(key, INT_MAX)) returns last occurance.
typedef tree<pair<int, int>, null_type, less<pair<int,int> >,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Policy End
// New Modular inverse short.
long long inv(long long a, long long md){ return 1<a ? md - inv(md%a,a)*md/a : 1; }
// This is random generator. Very useful.
mt19937_64 my_rand(std::random_device{}());
ll rnd(ll x){return my_rand()%x;}
#define iip pair<int,int>
#define llp pair<ll,ll>
#define MX 300005
#define MX2 1000009
int arr[MX];
int con1[MX2], con2[MX2], vis2[MX2];
vector<int> dist[MX];
vector<int> vis[MX2];

vector<int> get_divs(int val)
{
	vector<int> dv;
	for(int i=1;i*i<val;i++){
		if(val%i==0){
			if(vis2[i])dv.push_back(i);
			if(vis2[val/i])dv.push_back(val/i);
		}
	}
	int sq = sqrt(val);
	if(sq*sq==val && vis2[sq])dv.push_back(sq);
	return dv;
}

void input_fun()
{
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)cin>>arr[i], vis[arr[i]].push_back(i), vis2[arr[i]]++;
	set<int> prev;
	int mx = 0;
	for(int i=1;i<=n;i++){
		vector<int> divs = get_divs(arr[i]);
		for(int v:divs){
			if(prev.count(v)>0)con2[v] = con1[v]+1;
			else con2[v] = 1;
			int ind = i-con2[v]+1;
			auto lb = lower_bound(vis[v].begin(), vis[v].end(), ind);
			if(lb == vis[v].end() || *lb>i)continue;
			dist[con2[v]].push_back(i-con2[v]+1);
			mx = max(mx, con2[v]);
		}
		for(int s:prev){
			con1[s]=0;
		}
		for(int v:divs){
			con1[v] = con2[v];
		}
		prev.clear();
		for(int v:divs)prev.insert(v);
	}
	cout<<dist[mx].size()<<" "<<mx-1<<endl;
	for(int v:dist[mx]){
		cout<<v<<" ";
	}
	cout<<"\n";
}

int main()
{
	//freopen("/home/shajal/Desktop/input.txt", "r+", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);

    input_fun();
return 0;
}


//**********************************### With The name of Allah ###***********************************/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
// This section is for Policy Based Data Structure, more precisely Ordered Set.
// All Functions of set works here, in addition we have order_of_key() and find_by_order() function. find_by_order() returns iterator
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<functional>
using namespace __gnu_pbds;
// All unique value
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set1;
// For storing multiple occurance of same value we need to use pair. In pair first value is our key and second is useless count variable.
// order_of_key(make_pair(key, 0)) returns first occurance of a value, order_of_key(make_pair(key, INT_MAX)) returns last occurance.
typedef tree<pair<int, int>, null_type, less<pair<int,int> >,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Policy End
// Modular inverse short.
long long inv(long long a, long long md){ return 1<a ? md - inv(md%a,a)*md/a : 1; }
// random generator. Very useful.
mt19937_64 my_rand(std::random_device{}());
ll rnd(ll x){return my_rand()%x;}
// Binary Indexted Tree, Again, very useful.	Note: BIT is always indexed from 1 to n, not from 0.
vector<ll> BIT_array;	//Need to resize with required size
// Update value at index i. Here mx should be equal to BIT_array size.
void upd_BIT(int i,ll val, ll mx){for(;i<mx;i+=(i&-i))BIT_array[i]+=val;}
// This returns the sum of values from index 1 to i.
ll sum_BIT(int i){ll res=0;for(;i>0;i-=(i&-i))res+=BIT_array[i];return res;}
// This will return the first position where sum from 0 to pos is not less then s. We can also return the last position where sum less then s. For that return pos insted of pos+1.
ll pos_where_sum_not_less_then_s_BIT(ll s, ll mx){ll pos=0,sum=0;for(ll i=20;i>=0;i--)if(pos+(1<<i)<mx&&sum+BIT_array[pos+(1<<i)]<s)sum+=BIT_array[pos+(1<<i)],pos+=1<<i;return pos+1;}
#define PI atan(1)*4
#define iip pair<int,int>
#define llp pair<ll,ll>
#define MX 300009
int arr[MX], stree[MX*6], stree_ind[MX*6], lazy[MX*6];
int mx_len;
vector<int> res;
inline int leftt(int ind){return ind*2+1;}
inline int rightt(int ind){return ind*2+2;}

// Here l=0 and r=n-1 and st_ind =0  initially.
void build_tree(int l, int r, int st_ind)
{
	if(l==r){
		stree[st_ind] = arr[l];
		stree_ind[st_ind] = l;
		return;
	}
	int md = l + (r-l)/2;
	build_tree(l, md, leftt(st_ind));
	build_tree(md+1, r, rightt(st_ind));
	if(stree[leftt(st_ind)] < stree[rightt(st_ind)]){
		stree[st_ind] = stree[leftt(st_ind)];
		stree_ind[st_ind] = stree_ind[leftt(st_ind)];
	}
	else{
		stree[st_ind] = stree[rightt(st_ind)];
		stree_ind[st_ind] = stree_ind[rightt(st_ind)];
	}
}

void pushh(int st_ind)
{
	if(lazy[st_ind]!=0){
		stree[st_ind] += lazy[st_ind];
		lazy[leftt(st_ind)] += lazy[st_ind];
		lazy[rightt(st_ind)] += lazy[st_ind];
		lazy[st_ind] = 0;
	}
}

// st_ind starts from 0. Here val is added with all values in range qst to qen.
void update_util(int qst, int qen, int st, int en, int st_ind, ll val)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return;
	if(qst<=st&&qen>=en){
		stree[st_ind] += val;
		if(st != en){
			lazy[leftt(st_ind)] += val;
			lazy[rightt(st_ind)] += val;
		}
		return;
	}
	int mid = st + (en-st)/2;
	update_util(qst, qen, st, mid, leftt(st_ind), val);
	update_util(qst, qen, mid+1, en, rightt(st_ind), val);
}

llp query_util(int qst, int qen, int st, int en, int st_ind)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return {1e8, 0};
	if(qst<=st&&qen>=en){
		return make_pair(stree[st_ind], stree_ind[st_ind]);
	}
	int mid = st + (en-st)/2;
	llp lft = query_util(qst, qen, st, mid, leftt(st_ind));
	llp rgt = query_util(qst, qen, mid+1, en, rightt(st_ind));
	if(lft.first < rgt.first){
		return lft;
	}
	else {
		return rgt;
	}
}

void update_single(int ind, ll val, int n)
{
	update_util(ind, ind, 0, n-1, 0, val);
}

void update_range(int qst, int qen, ll val, int n)
{
	update_util(qst, qen, 0, n-1, 0, val);
}

llp query_range(int qst, int qen, int n)
{
	return query_util(qst, qen, 0, n-1, 0);
}
void calculate(int l, int r, int n)
{
	if(l>r)return;
	iip pp = query_range(l, r, n);
	int ind = pp.second;
	int lf = ind, rt = ind;
	while(lf>=l && arr[lf]%arr[ind]==0)lf--;
	while(rt<=r && arr[rt]%arr[ind]==0)rt++;
	int len = rt-lf-1;
	if(len>mx_len){
		res.clear();
		mx_len = len;
		res.push_back(lf+1);
	}
	else if(len == mx_len)res.push_back(lf+1);
	calculate(l, lf, n);
	calculate(rt, r, n);
}

void input_fun()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)cin>>arr[i];
	build_tree(0, n-1, 0);
	mx_len = 0;
	calculate(0, n-1, n);
	sort(res.begin(), res.end());
	cout<<res.size()<<" "<<mx_len-1<<endl;
	for(int v:res)cout<<v+1<<" ";
	cout<<endl;
}

int main()
{
	//freopen("/home/shajal/Desktop/input.txt", "r+", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);

    input_fun();
return 0;
}


//**********************************### With The name of Allah ###***********************************/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
// This section is for Policy Based Data Structure, more precisely Ordered Set.
// All Functions of set works here, in addition we have order_of_key() and find_by_order() function. find_by_order() returns iterator
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<functional>
using namespace __gnu_pbds;
// All unique value
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set1;
// For storing multiple occurance of same value we need to use pair. In pair first value is our key and second is useless count variable.
// order_of_key(make_pair(key, 0)) returns first occurance of a value, order_of_key(make_pair(key, INT_MAX)) returns last occurance.
typedef tree<pair<int, int>, null_type, less<pair<int,int> >,rb_tree_tag, tree_order_statistics_node_update> ordered_set;
// Policy End
// Modular inverse short.
long long inv(long long a, long long md){ return 1<a ? md - inv(md%a,a)*md/a : 1; }
// random generator. Very useful.
mt19937_64 my_rand(std::random_device{}());
ll rnd(ll x){return my_rand()%x;}
// Binary Indexted Tree, Again, very useful.	Note: BIT is always indexed from 1 to n, not from 0.
vector<ll> BIT_array;	//Need to resize with required size
// Update value at index i. Here mx should be equal to BIT_array size.
void upd_BIT(int i,ll val, ll mx){for(;i<mx;i+=(i&-i))BIT_array[i]+=val;}
// This returns the sum of values from index 1 to i.
ll sum_BIT(int i){ll res=0;for(;i>0;i-=(i&-i))res+=BIT_array[i];return res;}
// This will return the first position where sum from 0 to pos is not less then s. We can also return the last position where sum less then s. For that return pos insted of pos+1.
ll pos_where_sum_not_less_then_s_BIT(ll s, ll mx){ll pos=0,sum=0;for(ll i=20;i>=0;i--)if(pos+(1<<i)<mx&&sum+BIT_array[pos+(1<<i)]<s)sum+=BIT_array[pos+(1<<i)],pos+=1<<i;return pos+1;}
#define PI atan(1)*4
#define iip pair<int,int>
#define llp pair<ll,ll>
#define MX 300009
int arr[MX], stree[MX*6], stree_ind[MX*6], lazy[MX*6];
int mx_len;
vector<int> res;
inline int leftt(int ind){return ind*2+1;}
inline int rightt(int ind){return ind*2+2;}

// Here l=0 and r=n-1 and st_ind =0  initially.
void build_tree(int l, int r, int st_ind)
{
	if(l==r){
		stree[st_ind] = arr[l];
		stree_ind[st_ind] = l;
		return;
	}
	int md = l + (r-l)/2;
	build_tree(l, md, leftt(st_ind));
	build_tree(md+1, r, rightt(st_ind));
	if(stree[leftt(st_ind)] < stree[rightt(st_ind)]){
		stree[st_ind] = stree[leftt(st_ind)];
		stree_ind[st_ind] = stree_ind[leftt(st_ind)];
	}
	else{
		stree[st_ind] = stree[rightt(st_ind)];
		stree_ind[st_ind] = stree_ind[rightt(st_ind)];
	}
}

void pushh(int st_ind)
{
	if(lazy[st_ind]!=0){
		stree[st_ind] += lazy[st_ind];
		lazy[leftt(st_ind)] += lazy[st_ind];
		lazy[rightt(st_ind)] += lazy[st_ind];
		lazy[st_ind] = 0;
	}
}

// st_ind starts from 0. Here val is added with all values in range qst to qen.
void update_util(int qst, int qen, int st, int en, int st_ind, ll val)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return;
	if(qst<=st&&qen>=en){
		stree[st_ind] += val;
		if(st != en){
			lazy[leftt(st_ind)] += val;
			lazy[rightt(st_ind)] += val;
		}
		return;
	}
	int mid = st + (en-st)/2;
	update_util(qst, qen, st, mid, leftt(st_ind), val);
	update_util(qst, qen, mid+1, en, rightt(st_ind), val);
}

llp query_util(int qst, int qen, int st, int en, int st_ind)
{
	pushh(st_ind);
	if(qst>en||qen<st)
		return {1e8, 0};
	if(qst<=st&&qen>=en){
		return make_pair(stree[st_ind], stree_ind[st_ind]);
	}
	int mid = st + (en-st)/2;
	llp lft = query_util(qst, qen, st, mid, leftt(st_ind));
	llp rgt = query_util(qst, qen, mid+1, en, rightt(st_ind));
	if(lft.first < rgt.first){
		return lft;
	}
	else {
		return rgt;
	}
}

void update_single(int ind, ll val, int n)
{
	update_util(ind, ind, 0, n-1, 0, val);
}

void update_range(int qst, int qen, ll val, int n)
{
	update_util(qst, qen, 0, n-1, 0, val);
}

llp query_range(int qst, int qen, int n)
{
	return query_util(qst, qen, 0, n-1, 0);
}
void calculate(int l, int r, int n)
{
	if(l>r)return;
	iip pp = query_range(l, r, n);
	int ind = pp.second;
	int lf = ind, rt = ind;
	while(lf>=l && arr[lf]%arr[ind]==0)lf--;
	while(rt<=r && arr[rt]%arr[ind]==0)rt++;
	int len = rt-lf-1;
	if(len>mx_len){
		res.clear();
		mx_len = len;
		res.push_back(lf+1);
	}
	else if(len == mx_len)res.push_back(lf+1);
	calculate(l, ind-1, n);
	calculate(ind+1, r, n);
}

void input_fun()
{
	int n;
	cin>>n;
	for(int i=0;i<n;i++)cin>>arr[i];
	build_tree(0, n-1, 0);
	mx_len = 0;
	calculate(0, n-1, n);
	sort(res.begin(), res.end());
	cout<<res.size()<<" "<<mx_len-1<<endl;
	for(int v:res)cout<<v+1<<" ";
	cout<<endl;
}

int main()
{
	//freopen("/home/shajal/Desktop/input.txt", "r+", stdin);
    ios::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);

    input_fun();
return 0;
}


#include <bits/stdc++.h>//Carefully Crafted by hetp111
using namespace std;
#define int long long
#define double long double
#define all(v) (v).begin(),(v).end()
#define vi vector<int>
#define vvi vector<vi>
#define pii pair<int,int>
#define vii vector<pii>
#define MOD (1000000007)
#define MOD2 (998244353)
#define MOD3 (1000000009)
#define PI acos(-1)
#define eps (1e-8)
#define INF (1e18)
#define FASTER ios_base::sync_with_stdio(0);cin.tie(0)
template<class A,class B>ostream&operator<<(ostream&out,const pair<A,B>&a){return out<<"("<<a.first<<","<<a.second<<")";}
template<class A>ostream&operator<<(ostream&out,const vector<A>&a){for(const A &it:a)out<<it<<" ";return out;}
template<class A,class B>istream&operator>>(istream&in,pair<A,B>&a){return in>>a.first>>a.second;}
template<class A>istream&operator>>(istream&in,vector<A>&a){for(A &i:a)in>>i;return in;}
ifstream cinn("input.txt");ofstream coutt("output.txt");

int n,v[300005];

int tree[4*300005];

void makeit(int s,int e,int idx){
    if(s==e){
        tree[idx]=v[s];
        return;
    }
    int mid=(s+e)/2;
    makeit(s,mid,idx*2+1);
    makeit(mid+1,e,idx*2+2);
    tree[idx]=__gcd(tree[idx*2+1],tree[idx*2+2]);
}

int query(int s,int e,int S,int E,int idx){
    if(s>E || e<S)return -1;
    if(s>=S && e<=E)return tree[idx];
    int mid=(s+e)/2;
    int lolo=query(s,mid,S,E,idx*2+1);
    int olol=query(mid+1,e,S,E,idx*2+2);
    if(olol==-1)return lolo;
    if(lolo==-1)return olol;
    return __gcd(lolo,olol);
}

int gett(int a,int b){
    return query(0,n-1,a,b,0);
}

vi ans;
bool cnt[1000005];

bool f(int k){
    for(int i=0;i<=1000000;i++)cnt[i]=0;

    vi lo;
    for(int i=0;i<k;i++)cnt[v[i]]=1;

    if(cnt[gett(0,k-1)])lo.push_back(1);

    for(int i=k;i<n;i++){
        cnt[v[i-k]]=0;
        cnt[v[i]]=1;

        if(cnt[gett(i-k+1,i)])lo.push_back(i+2-k);
    }

    if(lo.empty())return 0;
    ans=lo;
    return 1;
}

signed main(){
    FASTER;
    cin>>n;
    for(int i=0;i<n;i++)cin>>v[i];
    makeit(0,n-1,0);

    int s=1,e=n;
    while(s<=e){
        int mid=(s+e)/2;
        if(f(mid))s=mid+1;
        else e=mid-1;
    }
    cout<<ans.size()<<" "<<s-2<<"\n"<<ans;
}