/**************************************************************
    Problem: ????
    User: (ina)xiaodongc
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:0 kb
    length:0 kb
    score: inf
****************************************************************/
/*
A possible implementation
The first few steps are just BST routine
Node deletion algorithm
Specifically, we're going to have a search
And assume that the target node does exist
So we call the removeAt routine
Remove the node physically
Next, we're still going through a for cycle
Ancestral ancestors traversing deleted nodes
Please pay special attention to our starting point
The father of the deleted node
Instead of inserting it like that
It can start directly from its grandfather
Then, in the course of the whole traversal
Each of us discovers an unbalanced ancestor G
Make a proper rotation adjustment to the ancestor
The three nodes involved in rotation are still G
And the taller kid, P
And the higher grandson V down there
And whether it's unbalanced or rotated
We all need to update the height of this ancestor
You can see that in the worst case
Really need to do logn times
You might as well take the control logic of the previous insert operation
Make a contrast here
No, there's nothing
Tricks to terminate the traversal process ahead of time
Because in the worst case
We really need to leave everything behind
Deal with all generations of ancestors
Since then, we can successfully end the algorithm
And return
So far you may find out
Here's the rotation
We haven't given a specific implementation of it
It's exactly what we suggested
Single spin and double spin in that way?
Interestingly enough, the answer is negative
*/
using namespace std;
#include<deque>
#include<stdint.h>
#include<set>
#include<stack>
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<map>
#define sqr(x) (x)*(x)
#define sort stable_sort
#define ll long long
#define mp make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mp(mp(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt"):
#define fast ios::sync_with_stdio(false);
void readi(int &x)
{
	int v=0,f=1;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readll(ll &x)
{
	ll v=0ll,f=1ll;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readc(char &x)
{
	char c;
	while ((c=getchar())==' ');
	x=c;
}
void writes(string s){puts(s.c_str());}
void writeln(){writes("");}
void writei(int x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
void writell(ll x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
ll qp(ll x,ll y)
{
	if (y==0) return 1;
	if (y==1) return x;
	ll z=qp(x,y/2);
	z=z*z%1000000007;
	if (y&1) z=z*x%1000000007;
	return z;
}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii>
#define piipi pair<pii,int>
#define plll pair<ll,pll>
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
/*************************************************/
int n,m,i,j,a[100005],b[5][5],c[100005];
vector<vector<int> > ans;
int main()
{
	cin>>n>>m;
	if (m==4)
	{
		if (n==1) {cout<<"YES\n2 4 1 3";return 0;}
		if (n==2) {cout<<"YES\n5 4 7 2\n3 6 1 8";return 0;}
		if (n==3) {cout<<"YES\n1 7 5 9\n10 2 12 3\n4 8 6 11";return 0;}
		if (n==4) {cout<<"YES\n1 4 11 8\n10 7 2 5\n3 16 9 14\n6 13 15 12";return 0;}
	}
	if (n==4)
	{
		if (m==1) {cout<<"YES\n2\n4\n1\n3\n";return 0;}
		if (m==2) {cout<<"YES\n2 5\n7 4\n6 1\n3 8";return 0;}
		if (m==3) {cout<<"YES\n1 10 4\n7 2 8\n5 12 6\n9 3 11";return 0;}
	}
	if (n<=3&&m<=3)
	{
		for (i=1;i<=m*n;i++) a[i]=i;
		do
		{
			int cnt=0;
			for (i=1;i<=n;i++)
			{
				for (j=1;j<=m;j++)
				{
					b[i][j]=a[++cnt];
				}
			}
			bool ok=1;
			for (i=1;i<=n&&ok;i++)
			{
				for (j=1;j<=m;j++)
				{
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-m) {ok=0;break;}
				}
			}
			if (ok)
			{
				cout<<"YES\n";
				for (i=1;i<=n;i++)
				{
					for (j=1;j<=m;j++)
					{
						cout<<b[i][j]<<' ';
					}
					cout<<endl;
				}
				return 0;
			}
		}while (next_permutation(a+1,a+n*m+1));
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	if (m>4)
	{
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);
			for (j=1;j<=m;j++)
			{
				cout<<(i-1)*m+a[j]<<' ';
			}
			cout<<endl;
		}
		return 0;}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				for (j=1;j<=m;j++)
				{
					if (i&1) cout<<(i-1)*m+c[j]<<' '; else cout<<(i-1)*m+a[j]<<' ';
				}
				cout<<endl;
			}
			return 0;
		}
	}
	else
	{
		swap(n,m);
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				ans.back().push_back((i-1)*m+a[j]);
			}
		}
		}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				if (i&1) ans.back().pb((i-1)*m+c[j]); else ans.back().pb((i-1)*m+a[j]);
			}
			}
		}
		swap(n,m);
		for (i=0;i<n;i++)
		{
			for (j=0;j<m;j++)
			{
				cout<<ans[j][i]<<' ';
			}
			cout<<endl;
		}
	}
	return 0;
}


/**************************************************************
    Problem: ????
    User: (ina)xiaodongc
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:0 kb
    length:0 kb
    score: inf
****************************************************************/
/*
A possible implementation
The first few steps are just BST routine
Node deletion algorithm
Specifically, we're going to have a search
And assume that the target node does exist
So we call the removeAt routine
Remove the node physically
Next, we're still going through a for cycle
Ancestral ancestors traversing deleted nodes
Please pay special attention to our starting point
The father of the deleted node
Instead of inserting it like that
It can start directly from its grandfather
Then, in the course of the whole traversal
Each of us discovers an unbalanced ancestor G
Make a proper rotation adjustment to the ancestor
The three nodes involved in rotation are still G
And the taller kid, P
And the higher grandson V down there
And whether it's unbalanced or rotated
We all need to update the height of this ancestor
You can see that in the worst case
Really need to do logn times
You might as well take the control logic of the previous insert operation
Make a contrast here
No, there's nothing
Tricks to terminate the traversal process ahead of time
Because in the worst case
We really need to leave everything behind
Deal with all generations of ancestors
Since then, we can successfully end the algorithm
And return
So far you may find out
Here's the rotation
We haven't given a specific implementation of it
It's exactly what we suggested
Single spin and double spin in that way?
Interestingly enough, the answer is negative
*/
using namespace std;
#include<deque>
#include<stdint.h>
#include<set>
#include<stack>
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<map>
#define sqr(x) (x)*(x)
#define sort stable_sort
#define ll long long
#define mp make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mp(mp(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt"):
#define fast ios::sync_with_stdio(false);
void readi(int &x)
{
	int v=0,f=1;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readll(ll &x)
{
	ll v=0ll,f=1ll;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readc(char &x)
{
	char c;
	while ((c=getchar())==' ');
	x=c;
}
void writes(string s){puts(s.c_str());}
void writeln(){writes("");}
void writei(int x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
void writell(ll x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
ll qp(ll x,ll y)
{
	if (y==0) return 1;
	if (y==1) return x;
	ll z=qp(x,y/2);
	z=z*z%1000000007;
	if (y&1) z=z*x%1000000007;
	return z;
}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii>
#define piipi pair<pii,int>
#define plll pair<ll,pll>
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
/*************************************************/
int n,m,i,j,a[100005],b[5][5],c[100005];
vector<vector<int> > ans;
int main()
{
	cin>>n>>m;
	if (m==4)
	{
		if (n==1) {cout<<"YES\n2 4 1 3";return 0;}
		if (n==2) {cout<<"YES\n5 4 7 2\n3 6 1 8";return 0;}
		if (n==3) {cout<<"YES\n1 7 5 9\n10 2 12 3\n4 8 6 11";return 0;}
		if (n==4) {cout<<"YES\n1 4 11 8\n10 7 2 5\n3 16 9 14\n6 13 15 12";return 0;}
	}
	if (n==4)
	{
		if (m==1) {cout<<"YES\n2\n4\n1\n3\n";return 0;}
		if (m==2) {cout<<"YES\n2 5\n7 4\n6 1\n3 8";return 0;}
		if (m==3) {cout<<"YES\n1 10 4\n7 2 8\n5 12 6\n9 3 11";return 0;}
	}
	if (n<=3&&m<=3)
	{
		for (i=1;i<=m*n;i++) a[i]=i;
		do
		{
			int cnt=0;
			for (i=1;i<=n;i++)
			{
				for (j=1;j<=m;j++)
				{
					b[i][j]=a[++cnt];
				}
			}
			bool ok=1;
			for (i=1;i<=n&&ok;i++)
			{
				for (j=1;j<=m;j++)
				{
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-m) {ok=0;break;}
				}
			}
			if (ok)
			{
				cout<<"YES\n";
				for (i=1;i<=n;i++)
				{
					for (j=1;j<=m;j++)
					{
						cout<<b[i][j]<<' ';
					}
					cout<<endl;
				}
				return 0;
			}
		}while (next_permutation(a+1,a+n*m+1));
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	if (n==3&&(m%2==0))
	{
		for (i=1;i<=n;i++)
		{
			if (i&1)
			{
				for (j=1;j<=m;j+=2) cout<<(i-1)*m+j<<' ';
				for (j=2;j<=m;j+=2) cout<<(i-1)*m+j<<' ';
			}
			else
			{
				for (j=2;j<=m;j+=2) cout<<(i-1)*m+j<<' ';
				for (j=1;j<=m;j+=2) cout<<(i-1)*m+j<<' ';
			}
			cout<<endl;
		}
		return 0;
	}
	if (m==3&&(n%2==0))
	{
		for (i=1;i<=m;i++)
		{
			vi e;
			ans.pb(e);
			if (i&1)
			{
				for (j=1;j<=n;j+=2) ans.back().pb((i-1)*n+j);
				for (j=2;j<=n;j+=2) ans.back().pb((i-1)*n+j);
			}
			else
			{
				for (j=2;j<=n;j+=2) ans.back().pb((i-1)*n+j);
				for (j=1;j<=n;j+=2) ans.back().pb((i-1)*n+j);
			}
		}
		for (i=0;i<n;i++)
		{
			for (j=0;j<m;j++)
			{
				cout<<ans[j][i]<<' ';
			}
			cout<<endl;
		}
		return 0;
	}
	if (m>4)
	{
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);
			for (j=1;j<=m;j++)
			{
				cout<<(i-1)*m+a[j]<<' ';
			}
			cout<<endl;
		}
		return 0;}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				for (j=1;j<=m;j++)
				{
					if (i&1) cout<<(i-1)*m+c[j]<<' '; else cout<<(i-1)*m+a[j]<<' ';
				}
				cout<<endl;
			}
			return 0;
		}
	}
	else
	{
		swap(n,m);
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				ans.back().push_back((i-1)*m+a[j]);
			}
		}
		}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				if (i&1) ans.back().pb((i-1)*m+c[j]); else ans.back().pb((i-1)*m+a[j]);
			}
			}
		}
		swap(n,m);
		for (i=0;i<n;i++)
		{
			for (j=0;j<m;j++)
			{
				cout<<ans[j][i]<<' ';
			}
			cout<<endl;
		}
	}
	return 0;
}


/**************************************************************
    Problem: ????
    User: (ina)xiaodongc
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:0 kb
    length:0 kb
    score: inf
****************************************************************/
/*
A possible implementation
The first few steps are just BST routine
Node deletion algorithm
Specifically, we're going to have a search
And assume that the target node does exist
So we call the removeAt routine
Remove the node physically
Next, we're still going through a for cycle
Ancestral ancestors traversing deleted nodes
Please pay special attention to our starting point
The father of the deleted node
Instead of inserting it like that
It can start directly from its grandfather
Then, in the course of the whole traversal
Each of us discovers an unbalanced ancestor G
Make a proper rotation adjustment to the ancestor
The three nodes involved in rotation are still G
And the taller kid, P
And the higher grandson V down there
And whether it's unbalanced or rotated
We all need to update the height of this ancestor
You can see that in the worst case
Really need to do logn times
You might as well take the control logic of the previous insert operation
Make a contrast here
No, there's nothing
Tricks to terminate the traversal process ahead of time
Because in the worst case
We really need to leave everything behind
Deal with all generations of ancestors
Since then, we can successfully end the algorithm
And return
So far you may find out
Here's the rotation
We haven't given a specific implementation of it
It's exactly what we suggested
Single spin and double spin in that way?
Interestingly enough, the answer is negative
*/
using namespace std;
#include<deque>
#include<stdint.h>
#include<set>
#include<stack>
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<map>
#define sqr(x) (x)*(x)
#define sort stable_sort
#define ll long long
#define mp make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mp(mp(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt"):
#define fast ios::sync_with_stdio(false);
void readi(int &x)
{
	int v=0,f=1;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readll(ll &x)
{
	ll v=0ll,f=1ll;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readc(char &x)
{
	char c;
	while ((c=getchar())==' ');
	x=c;
}
void writes(string s){puts(s.c_str());}
void writeln(){writes("");}
void writei(int x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
void writell(ll x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
ll qp(ll x,ll y)
{
	if (y==0) return 1;
	if (y==1) return x;
	ll z=qp(x,y/2);
	z=z*z%1000000007;
	if (y&1) z=z*x%1000000007;
	return z;
}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii>
#define piipi pair<pii,int>
#define plll pair<ll,pll>
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
/*************************************************/
int n,m,i,j,a[100005],b[5][5],c[100005];
vector<vector<int> > ans;
int main()
{
	cin>>n>>m;
	if (m==4)
	{
		if (n==1) {cout<<"YES\n2 1 4 3";return 0;}
		if (n==2) {cout<<"YES\n5 4 7 2\n3 6 1 8";return 0;}
		if (n==3) {cout<<"YES\n1 7 5 9\n10 2 12 3\n4 8 6 11";return 0;}
		if (n==4) {cout<<"YES\n1 4 11 8\n10 7 2 5\n3 16 9 14\n6 13 15 12";return 0;}
	}
	if (n==4)
	{
		if (m==1) {cout<<"YES\n2\n1\n4\n3\n";return 0;}
		if (m==2) {cout<<"YES\n5 3\n4 6\n7 1\n2 8";return 0;}
		if (m==3) {cout<<"YES\n1 10 4\n7 2 8\n5 12 6\n9 3 11";return 0;}
	}
	if (n<=3&&m<=3)
	{
		for (i=1;i<=m*n;i++) a[i]=i;
		do
		{
			int cnt=0;
			for (i=1;i<=n;i++)
			{
				for (j=1;j<=m;j++)
				{
					b[i][j]=a[++cnt];
				}
			}
			bool ok=1;
			for (i=1;i<=n&&ok;i++)
			{
				for (j=1;j<=m;j++)
				{
					if (b[i][j+1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j+1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j+1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j+1]==b[i][j]-m) {ok=0;break;}
					if (b[i][j-1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j-1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j-1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j-1]==b[i][j]-m) {ok=0;break;}
					if (b[i+1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i+1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i+1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i+1][j]==b[i][j]-m) {ok=0;break;}
					if (b[i-1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i-1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i-1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i-1][j]==b[i][j]-m) {ok=0;break;}
				}
			}
			if (ok)
			{
				cout<<"YES\n";
				for (i=1;i<=n;i++)
				{
					for (j=1;j<=m;j++)
					{
						cout<<b[i][j]<<' ';
					}
					cout<<endl;
				}
				return 0;
			}
		}while (next_permutation(a+1,a+n*m+1));
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	if (m>4)
	{
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);
			for (j=1;j<=m;j++)
			{
				cout<<(i-1)*m+a[j]<<' ';
			}
			cout<<endl;
		}
		return 0;}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				for (j=1;j<=m;j++)
				{
					if (i&1) cout<<(i-1)*m+c[j]<<' '; else cout<<(i-1)*m+a[j]<<' ';
				}
				cout<<endl;
			}
			return 0;
		}
	}
	else
	{
		swap(n,m);
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				ans.back().push_back((i-1)*m+a[j]);
			}
		}
		}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				if (i&1) ans.back().pb((i-1)*m+c[j]); else ans.back().pb((i-1)*m+a[j]);
			}
			}
		}
		swap(n,m);
		for (i=0;i<n;i++)
		{
			for (j=0;j<m;j++)
			{
				cout<<ans[j][i]<<' ';
			}
			cout<<endl;
		}
	}
	return 0;
}


/**************************************************************
    Problem: ????
    User: (ina)xiaodongc
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:0 kb
    length:0 kb
    score: inf
****************************************************************/
/*
A possible implementation
The first few steps are just BST routine
Node deletion algorithm
Specifically, we're going to have a search
And assume that the target node does exist
So we call the removeAt routine
Remove the node physically
Next, we're still going through a for cycle
Ancestral ancestors traversing deleted nodes
Please pay special attention to our starting point
The father of the deleted node
Instead of inserting it like that
It can start directly from its grandfather
Then, in the course of the whole traversal
Each of us discovers an unbalanced ancestor G
Make a proper rotation adjustment to the ancestor
The three nodes involved in rotation are still G
And the taller kid, P
And the higher grandson V down there
And whether it's unbalanced or rotated
We all need to update the height of this ancestor
You can see that in the worst case
Really need to do logn times
You might as well take the control logic of the previous insert operation
Make a contrast here
No, there's nothing
Tricks to terminate the traversal process ahead of time
Because in the worst case
We really need to leave everything behind
Deal with all generations of ancestors
Since then, we can successfully end the algorithm
And return
So far you may find out
Here's the rotation
We haven't given a specific implementation of it
It's exactly what we suggested
Single spin and double spin in that way?
Interestingly enough, the answer is negative
*/
using namespace std;
#include<deque>
#include<stdint.h>
#include<set>
#include<stack>
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<map>
#define sqr(x) (x)*(x)
#define sort stable_sort
#define ll long long
#define mp make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mp(mp(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt"):
#define fast ios::sync_with_stdio(false);
void readi(int &x)
{
	int v=0,f=1;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readll(ll &x)
{
	ll v=0ll,f=1ll;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readc(char &x)
{
	char c;
	while ((c=getchar())==' ');
	x=c;
}
void writes(string s){puts(s.c_str());}
void writeln(){writes("");}
void writei(int x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
void writell(ll x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
ll qp(ll x,ll y)
{
	if (y==0) return 1;
	if (y==1) return x;
	ll z=qp(x,y/2);
	z=z*z%1000000007;
	if (y&1) z=z*x%1000000007;
	return z;
}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii>
#define piipi pair<pii,int>
#define plll pair<ll,pll>
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
/*************************************************/
int n,m,i,j,a[100005],b[5][5],c[100005];
vector<vector<int> > ans;
int main()
{
	cin>>n>>m;
	if (m==4)
	{
		if (n==1) {cout<<"YES\n2 4 1 3";return 0;}
		if (n==2) {cout<<"YES\n5 4 7 2\n3 6 1 8";return 0;}
		if (n==3) {cout<<"YES\n1 7 5 9\n10 2 12 3\n4 8 6 11";return 0;}
		if (n==4) {cout<<"YES\n1 4 11 8\n10 7 2 5\n3 16 9 14\n6 13 15 12";return 0;}
	}
	if (n==4)
	{
		if (m==1) {cout<<"YES\n2\n4\n1\n3\n";return 0;}
		if (m==2) {cout<<"YES\n5 3\n4 6\n7 1\n2 8";return 0;}
		if (m==3) {cout<<"YES\n1 10 4\n7 2 8\n5 12 6\n9 3 11";return 0;}
	}
	if (n<=3&&m<=3)
	{
		for (i=1;i<=m*n;i++) a[i]=i;
		do
		{
			int cnt=0;
			for (i=1;i<=n;i++)
			{
				for (j=1;j<=m;j++)
				{
					b[i][j]=a[++cnt];
				}
			}
			bool ok=1;
			for (i=1;i<=n&&ok;i++)
			{
				for (j=1;j<=m;j++)
				{
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-m) {ok=0;break;}
				}
			}
			if (ok)
			{
				cout<<"YES\n";
				for (i=1;i<=n;i++)
				{
					for (j=1;j<=m;j++)
					{
						cout<<b[i][j]<<' ';
					}
					cout<<endl;
				}
				return 0;
			}
		}while (next_permutation(a+1,a+n*m+1));
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	if (m>4)
	{
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);
			for (j=1;j<=m;j++)
			{
				cout<<(i-1)*m+a[j]<<' ';
			}
			cout<<endl;
		}
		return 0;}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				for (j=1;j<=m;j++)
				{
					if (i&1) cout<<(i-1)*m+c[j]<<' '; else cout<<(i-1)*m+a[j]<<' ';
				}
				cout<<endl;
			}
			return 0;
		}
	}
	else
	{
		swap(n,m);
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				ans.back().push_back((i-1)*m+a[j]);
			}
		}
		}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				if (i&1) ans.back().pb((i-1)*m+c[j]); else ans.back().pb((i-1)*m+a[j]);
			}
			}
		}
		swap(n,m);
		for (i=0;i<n;i++)
		{
			for (j=0;j<m;j++)
			{
				cout<<ans[j][i]<<' ';
			}
			cout<<endl;
		}
	}
	return 0;
}


/**************************************************************
    Problem: ????
    User: (ina)xiaodongc
    Language: C++
    Result: Accepted
    Time:0 ms
    Memory:0 kb
    length:0 kb
    score: inf
****************************************************************/
/*
A possible implementation
The first few steps are just BST routine
Node deletion algorithm
Specifically, we're going to have a search
And assume that the target node does exist
So we call the removeAt routine
Remove the node physically
Next, we're still going through a for cycle
Ancestral ancestors traversing deleted nodes
Please pay special attention to our starting point
The father of the deleted node
Instead of inserting it like that
It can start directly from its grandfather
Then, in the course of the whole traversal
Each of us discovers an unbalanced ancestor G
Make a proper rotation adjustment to the ancestor
The three nodes involved in rotation are still G
And the taller kid, P
And the higher grandson V down there
And whether it's unbalanced or rotated
We all need to update the height of this ancestor
You can see that in the worst case
Really need to do logn times
You might as well take the control logic of the previous insert operation
Make a contrast here
No, there's nothing
Tricks to terminate the traversal process ahead of time
Because in the worst case
We really need to leave everything behind
Deal with all generations of ancestors
Since then, we can successfully end the algorithm
And return
So far you may find out
Here's the rotation
We haven't given a specific implementation of it
It's exactly what we suggested
Single spin and double spin in that way?
Interestingly enough, the answer is negative
*/
using namespace std;
#include<deque>
#include<stdint.h>
#include<set>
#include<stack>
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<iomanip>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<map>
#define sqr(x) (x)*(x)
#define sort stable_sort
#define ll long long
#define mp make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mp(mp(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt"):
#define fast ios::sync_with_stdio(false);
void readi(int &x)
{
	int v=0,f=1;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readll(ll &x)
{
	ll v=0ll,f=1ll;
	char c=getchar();
	while (!isdigit(c)&&c!='-') c=getchar();
	if (c=='-') f=-1; else v=v*10+c-'0';
	while (isdigit(c=getchar())) v=v*10+c-'0';
	x=v*f;
}
void readc(char &x)
{
	char c;
	while ((c=getchar())==' ');
	x=c;
}
void writes(string s){puts(s.c_str());}
void writeln(){writes("");}
void writei(int x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
void writell(ll x)
{
	if (!x) putchar('0');
	char a[25];
	int top=0;
	while (x)
	{
		a[++top]=(x%10)+'0';
		x/=10;
	}
	while (top)
	{
		putchar(a[top]);
		top--;
	}
}
ll qp(ll x,ll y)
{
	if (y==0) return 1;
	if (y==1) return x;
	ll z=qp(x,y/2);
	z=z*z%1000000007;
	if (y&1) z=z*x%1000000007;
	return z;
}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii>
#define piipi pair<pii,int>
#define plll pair<ll,pll>
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
/*************************************************/
int n,m,i,j,a[100005],b[5][5],c[100005];
vector<vector<int> > ans;
int main()
{
	cin>>n>>m;
	if (m==4)
	{
		if (n==1) {cout<<"YES\n2 1 4 3";return 0;}
		if (n==2) {cout<<"YES\n5 4 7 2\n3 6 1 8";return 0;}
		if (n==3) {cout<<"YES\n1 7 5 9\n10 2 12 3\n4 8 6 11";return 0;}
		if (n==4) {cout<<"YES\n1 4 11 8\n10 7 2 5\n3 16 9 14\n6 13 15 12";return 0;}
	}
	if (n==4)
	{
		if (m==1) {cout<<"YES\n2\n1\n4\n3\n";return 0;}
		if (m==2) {cout<<"YES\n5 3\n4 6\n7 1\n2 8";return 0;}
		if (m==3) {cout<<"YES\n1 10 4\n7 2 8\n5 12 6\n9 3 11";return 0;}
	}
	if (n<=3&&m<=3)
	{
		for (i=1;i<=m*n;i++) a[i]=i;
		do
		{
			int cnt=0;
			for (i=1;i<=n;i++)
			{
				for (j=1;j<=m;j++)
				{
					b[i][j]=a[++cnt];
				}
			}
			bool ok=1;
			for (i=1;i<=n&&ok;i++)
			{
				for (j=1;j<=m;j++)
				{
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j+1]&&b[i][j+1]==b[i][j]-m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-1) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]+m) {ok=0;break;}
					if (b[i][j-1]&&b[i][j-1]==b[i][j]-m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i+1][j]&&b[i+1][j]==b[i][j]-m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-1) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]+m) {ok=0;break;}
					if (b[i-1][j]&&b[i-1][j]==b[i][j]-m) {ok=0;break;}
				}
			}
			if (ok)
			{
				cout<<"YES\n";
				for (i=1;i<=n;i++)
				{
					for (j=1;j<=m;j++)
					{
						cout<<b[i][j]<<' ';
					}
					cout<<endl;
				}
				return 0;
			}
		}while (next_permutation(a+1,a+n*m+1));
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	if (m>4)
	{
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);
			for (j=1;j<=m;j++)
			{
				cout<<(i-1)*m+a[j]<<' ';
			}
			cout<<endl;
		}
		return 0;}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				for (j=1;j<=m;j++)
				{
					if (i&1) cout<<(i-1)*m+c[j]<<' '; else cout<<(i-1)*m+a[j]<<' ';
				}
				cout<<endl;
			}
			return 0;
		}
	}
	else
	{
		swap(n,m);
		int cnt=0;
		for (i=1;i<=(m+1)/2;i++)
		{
			a[++cnt]=i;
			a[++cnt]=i+(m+1)/2;
		}
		//for (i=1;i<=m;i++) cout<<a[i]<<' ';
		if (m%2==0) {for (i=1;i<=n;i++)
		{
			reverse(a+1,a+m+1);vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				ans.back().push_back((i-1)*m+a[j]);
			}
		}
		}
		else{
			int cnt=0;
			for (i=1;i<=m/2;i++)
			{
				c[++cnt]=i+(m+1)/2-1;
				c[++cnt]=i;
			}
			c[++cnt]=m;
			for (i=1;i<=n;i++)
			{
				//reverse(c+1,c+m+1);
				vi e;
			ans.push_back(e);
			for (j=1;j<=m;j++)
			{
				if (i&1) ans.back().pb((i-1)*m+c[j]); else ans.back().pb((i-1)*m+a[j]);
			}
			}
		}
		swap(n,m);
		for (i=0;i<n;i++)
		{
			for (j=0;j<m;j++)
			{
				cout<<ans[j][i]<<' ';
			}
			cout<<endl;
		}
	}
	return 0;
}


#include <bits/stdc++.h>
#define lim n*m
using namespace std;

int n,m;
const int maxn=100010;
vector<int>ve[maxn];
bool flag[maxn];

inline void dfs(int x,int y){
	if(x==n&&y==m+1){
		puts("YES");
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++)
				printf("%d ",ve[i][j]);
			printf("\n");
		}
		exit(0);
	}
	if(y==m+1)x++,y=1;
	for(int i=1;i<=lim;i++)if(!flag[i]){
		if(ve[x][y-1]-1==i)continue;
		if(ve[x][y-1]+1==i)continue;
		if(ve[x][y-1]-m==i)continue;
		if(ve[x][y-1]+m==i)continue;
		if(ve[x-1][y]-1==i)continue;
		if(ve[x-1][y]+1==i)continue;
		if(ve[x-1][y]-m==i)continue;
		if(ve[x-1][y]+m==i)continue;
		ve[x][y]=i;flag[i]=true;
		dfs(x,y+1);
		ve[x][y]=0;flag[i]=false;
	}
}

int main(){
#ifdef YSW
	freopen("data.in","r",stdin);
#endif
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n+1;i++)
		for(int j=0;j<=m+1;j++)
			ve[i].push_back(-1);
	dfs(1,1);
	puts("NO");
	return 0;
}
/*
2 4
*/


#include <bits/stdc++.h>
#define lim n*m
using namespace std;

int n,m;
const int maxn=1e5+10;
const int inf =1e9;
bool flag[maxn];
vector<int>ve[maxn];
set<int>s;

inline void dfs(int x,int y){
	if(x==n&&y==m+1){
		puts("YES");
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++)
				printf("%d ",ve[i][j]);
			printf("\n");
		}
		exit(0);
	}
	if(y==m+1)x++,y=1;
	for(auto i=s.begin();i!=s.end();){
		int num=*i;i++;
		if(ve[x][y-1]-1==num)continue;
		if(ve[x][y-1]+1==num)continue;
		if(ve[x][y-1]-m==num)continue;
		if(ve[x][y-1]+m==num)continue;
		if(ve[x-1][y]-1==num)continue;
		if(ve[x-1][y]+1==num)continue;
		if(ve[x-1][y]-m==num)continue;
		if(ve[x-1][y]+m==num)continue;
		s.erase(num);
		ve[x][y]=num;
		dfs(x,y+1);
		s.insert(num);
	}
}

int main(){
#ifdef YSW
	freopen("data.in","r",stdin);
#endif
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n+1;i++)
		for(int j=0;j<=m+1;j++)
			ve[i].push_back(-inf);
	for(int i=1;i<=lim;i++)s.insert(i);
	dfs(1,1);
	puts("NO");
	return 0;
}
/*
2 4
*/


#include <bits/stdc++.h>
#define lim n*m
using namespace std;

int n,m;
const int maxn=1e5+10;
const int inf =1e9;
bool flag[maxn];
vector<int>ve[maxn];
set<int>s;

inline void dfs(int x,int y){
	if(x==n&&y==m+1){
		puts("YES");
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++)
				printf("%d ",ve[i][j]);
			printf("\n");
		}
		exit(0);
	}
	if(y==m+1)x++,y=1;
	for(auto i=s.begin();i!=s.end();i++){
		int num=*i;
		if(ve[x][y-1]-1==num)continue;
		if(ve[x][y-1]+1==num)continue;
		if(ve[x][y-1]-m==num)continue;
		if(ve[x][y-1]+m==num)continue;
		if(ve[x-1][y]-1==num)continue;
		if(ve[x-1][y]+1==num)continue;
		if(ve[x-1][y]-m==num)continue;
		if(ve[x-1][y]+m==num)continue;
		s.erase(num);
		ve[x][y]=num;
		dfs(x,y+1);
		s.insert(num);
		i=s.find(num);
	}
}

int main(){
#ifdef YSW
	freopen("data.in","r",stdin);
#endif
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n+1;i++)
		for(int j=0;j<=m+1;j++)
			ve[i].push_back(-inf);
	for(int i=1;i<=lim;i++)s.insert(i);
	dfs(1,1);
	puts("NO");
	return 0;
}
/*
2 4
*/


#include <bits/stdc++.h>
#define lim n*m
using namespace std;

int n,m;
const int maxn=100010;
vector<int>ve[maxn];
bool flag[maxn];

inline void dfs(int x,int y){
	if(x==n&&y==m+1){
		puts("YES");
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++)
				printf("%d ",ve[i][j]);
			printf("\n");
		}
		exit(0);
	}
	if(y==m+1)x++,y=1;
	for(int i=1;i<=lim;i++)if(!flag[i]){
		if(ve[x][y-1]-1==i)continue;
		if(ve[x][y-1]+1==i)continue;
		if(ve[x][y-1]-m==i)continue;
		if(ve[x][y-1]+m==i)continue;
		if(ve[x-1][y]-1==i)continue;
		if(ve[x-1][y]+1==i)continue;
		if(ve[x-1][y]-m==i)continue;
		if(ve[x-1][y]+m==i)continue;
		ve[x][y]=i;flag[i]=true;
		dfs(x,y+1);
		ve[x][y]=0;flag[i]=false;
	}
}

int main(){
#ifdef YSW
	freopen("data.in","r",stdin);
#endif
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n;i++)ve[i].push_back(-1);
	dfs(1,1);
	puts("NO");
	return 0;
}
/*
2 4
*/


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = 0;
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }

        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 5){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;
    }else if(a == 4){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);

            } else{

                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);
                swap(grid[0][j],grid[3][j]);
                swap(grid[2][j], grid[1][j]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }

        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = b - 1;
            for( int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j--;
            }
            for(int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j--;
            }
        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 5){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
            } else{
                int i = a - 1;
                for( int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i--;
                }
                for(int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i--;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;
    }else if(a == 4){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);

            } else{

                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);
                swap(grid[0][j],grid[3][j]);
                swap(grid[2][j], grid[1][j]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }

        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = 0;
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }

        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 5){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;

    }else if(a == 4){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);

            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }

                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);
                swap(grid[0][j],grid[3][j]);
                swap(grid[2][j], grid[1][j]);

            }
        }

        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }

        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = 0;
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }

        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 5){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;

    }else if(a == 4){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);

            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }

            }
        }

        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }

        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = 0;
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }

        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 4){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = 0;
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }

        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 5){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;

    }else if(a == 4){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);

            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }

                swap(grid[0][j],grid[3][j]);
                swap(grid[2][j], grid[1][j]);

            }
        }

        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }

        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = 0;
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }

        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 5){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
            } else{
                int i = 0;
                for(int k = b; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + k + 1;
                    i++;
                }
                for( int k = 0; k < (a - 1)*b + j + 1; k+=2*b){
                    grid[i][j] = j + 1 + k;
                    i++;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#include <iostream>
#include <vector>
#include <set>

using namespace std;

#define _USE_MATH_DEFINES

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;

#define nl '\n'
typedef istringstream iss;
#define pb push_back;
#define ins insert;
#define multiset mset;
#define getl(A) getline(cin, A);

const ll INF =  0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    int a, b;
    cin >> a >> b;
    if( a == 1 && b == 1){
        cout << "YES" << nl;
        cout << 1;
        return 0;
    }

    int grid[a][b];

    // i <= j
    if(b >= 5){
    for(int i = 0; i < a; ++i){
        if(i % 2 == 0){
            int j = 0;
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
        } else{
            int j = 0;
            for(int k = 1; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }
            for( int k = 0; k < b; k+=2){
                grid[i][j] = i*b + k + 1;
                j++;
            }

        }
    }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    } else if ( a >= 5){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
            } else{
                int i = 0;
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;

    } else if( a == 3 && b == 3){
        cout << "YES" << nl;
        cout << 2 << " " << 7 << " " << 6 << nl;
        cout << 9 << " " << 5 << " " << 1 << nl;
        cout << 4 << " " << 3 << " " << 8 << nl;
        return 0;
    }else if(a == 4){
        for(int j = 0; j < b; ++j){
            if(j % 2 == 0){
                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);

            } else{

                int i = 0;
                for( int k = 0; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                for(int k = 1; k < a; k+=2){
                    grid[i][j] = j*a + k + 1;
                    i++;
                }
                swap(grid[0][j],grid[1][j]);
                swap(grid[3][j], grid[2][j]);
                swap(grid[0][j],grid[3][j]);
                swap(grid[2][j], grid[1][j]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }

        return 0;
    }else if(b == 4){
        for(int i = 0; i < a; ++i){
            if(i % 2 == 0){
                int j = 0;
                for( int k = 0; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                for(int k = 1; k < b; k+=2){
                    grid[i][j] = i*b + k + 1;
                    j++;
                }
                swap(grid[i][0],grid[i][1]);
                swap(grid[i][3], grid[i][2]);
            } else{

                    int j = 0;
                    for( int k = 0; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    for(int k = 1; k < b; k+=2){
                        grid[i][j] = i*b + k + 1;
                        j++;
                    }
                    swap(grid[i][0],grid[i][1]);
                    swap(grid[i][3], grid[i][2]);
                    swap(grid[i][0],grid[i][3]);
                    swap(grid[i][2], grid[i][1]);

            }
        }
        cout << "YES" << nl;
        for(int k = 0; k < a; k++){
            for(int m = 0; m < b; m++){
                cout << grid[k][m] << " ";
            }
            cout << nl;
        }
        return 0;
    }
    else{
        cout << "NO";
        return 0;
    }

}


#pragma comment(linker, "/STACK:268435456")
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <iomanip>
#include <stack>
#include <string>
#include <set>
#include <queue>
#include <functional>
#include <deque>
#include <cmath>
#include <sstream>
#include <bitset>
#include <list>

using namespace std;

#define forn(i,s,n) for(int i = s; i < n; i++)
#define forr(i,s,n) for(int i = s; i > n; i--)
#define forrw(i,s,n) for(int i = s; i >= n; i--)
#define fornw(i,s,n) for(int i = s; i <= n; i++)
#define ALL(x) x.begin(),x.end()
#define mp(x,y) make_pair(x,y)
#define lson x*2, l, m
#define rson x*2+1, m+1, r
#define sf(x,y) scanf("%" x,&y)
#define pf(x,y) printf("%" x,y)
#define getb(x,y) ((x >> y) & 1)
#define setb1(x,y) x = (x|(1<<y))
#define setb0(x,y) x = ((x|(1<<y))^(1<<y))

typedef long long int64;
typedef unsigned long long uint64;
typedef pair<int, int> pii;
typedef pair<int64, int64> pii64;
typedef vector<int> vint;
typedef vector<int64> vint64;
typedef long double float64;
template <typename T1, typename T2> istream& operator >> (istream& in, pair<T1, T2>& t) { return in >> t.first >> t.second; }
template <typename T1, typename T2> ostream& operator << (ostream& out, pair<T1, T2>& t) { return out << t.first << " " << t.second << endl; }
template <typename T> istream& operator >> (istream& in, vector<T>& t) { for (int i = 0; i < t.size(); i++) in >> t[i]; return in; }
template <typename T> ostream& operator << (ostream& out, vector<T>& t) { for (int i = 0; i < t.size(); i++) out << t[i] << " "; return out; }

int n, m;
vector<vint> v;

vector<vint> turn(vector<vint>& v1)
{
	vector<vint> v2(m, vint(n));
	int i1 = 0, j1 = 0;
	for (auto i : v1)
	{
		for (auto j : i)
		{
			v2[i1][j1] = j;
			i1++; if (i1 == m)j1++, i1 = 0;
		}
	}
	return v2;
}

void fill(vector<vint>& v)
{
	int sch = 1;
	for (auto& i : v)
	{
		for (auto& j : i)
		{
			j = sch++;
		}
	}
}

void solve1()
{
	bool is = n > m;
	if (is) v = turn(v), swap(n,m);

	for (int i = 0; i < n; i++)
	{
		if (i % 2 == 1)continue;
		rotate(v[i].begin(), v[i].begin() + 2, v[i].end());
	}

	for (int i = 0; i < m; i++)
	{
		if (i % 2 == 1)continue;
		int l = v[n - 1][i];
		v[n - 1][i] = v[0][i];
		for (int j = n - 2; j >= 0; j--)
		{
			int t = v[j][i];
			v[j][i] = l;
			l = t;
		}
	}
	if (is) v = turn(v), swap(n, m);
	cout << "YES" << endl;
	{
		for (auto i : v)
		{
			cout << i << endl;
		}
	}
	exit(0);
}

void solve2()
{
	bool is = n < m;
	if (n > m)swap(n, m);
	vint q(m);
	int i = 0;
	for (int r = 1; r <= m; r += 2)
	{
		q[i++] = r;
	}
	for (int r = 2; r <= m; r += 2)
	{
		q[i++] = r;
	}
	cout << "YES" << endl;
	if (is)cout << q << endl;
	else
	{
		for (int i : q)cout << i << endl;
}
	exit(0);
}

int main()
{
#ifdef _SANYA
	freopen("abc.txt", "r", stdin);
#else
#define T "lepus"
	//freopen(T ".in", "r", stdin);
	//freopen(T ".out", "w", stdout);
#endif
	cin >> n >> m;
	v.assign(n, vint(m));
	fill(v);
	if (n == m && n == 1)return puts("YES\n1");
	if ((n >= 2 && m >= 4) || (m >= 2 && n >= 4))solve1();
	if ((n == 1 && (m == 2 || m == 3))
		|| (n == 2 && (m == 1 || m == 2 || m == 3))
		|| (m == 1 && (n == 2 || n == 3))
		|| (m == 2 && (n == 1 || n == 2 || n == 3)))return puts("NO");
	if (n == 3 && m == 3)
	{
		vector<vint> v = { {6,1,8}, {7,5,3}, {2,9,4} };
		cout << "YES" << endl;
		for (auto i : v)
		{
			cout << i << endl;
		}
		exit(0);
	}
	if (n == 1 && m == 4) return puts("YES\n2 4 1 3");
	if (n == 4 && m == 1) return puts("YES\n2\n4\n1\n3");
	if (n == 1 || m == 1)solve2();
	return 0;
}


#pragma comment(linker, "/STACK:268435456")
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <iomanip>
#include <stack>
#include <string>
#include <set>
#include <queue>
#include <functional>
#include <deque>
#include <cmath>
#include <sstream>
#include <bitset>
#include <list>

using namespace std;

#define forn(i,s,n) for(int i = s; i < n; i++)
#define forr(i,s,n) for(int i = s; i > n; i--)
#define forrw(i,s,n) for(int i = s; i >= n; i--)
#define fornw(i,s,n) for(int i = s; i <= n; i++)
#define ALL(x) x.begin(),x.end()
#define mp(x,y) make_pair(x,y)
#define lson x*2, l, m
#define rson x*2+1, m+1, r
#define sf(x,y) scanf("%" x,&y)
#define pf(x,y) printf("%" x,y)
#define getb(x,y) ((x >> y) & 1)
#define setb1(x,y) x = (x|(1<<y))
#define setb0(x,y) x = ((x|(1<<y))^(1<<y))

typedef long long int64;
typedef unsigned long long uint64;
typedef pair<int, int> pii;
typedef pair<int64, int64> pii64;
typedef vector<int> vint;
typedef vector<int64> vint64;
typedef long double float64;
template <typename T1, typename T2> istream& operator >> (istream& in, pair<T1, T2>& t) { return in >> t.first >> t.second; }
template <typename T1, typename T2> ostream& operator << (ostream& out, pair<T1, T2>& t) { return out << t.first << " " << t.second << endl; }
template <typename T> istream& operator >> (istream& in, vector<T>& t) { for (int i = 0; i < t.size(); i++) in >> t[i]; return in; }
template <typename T> ostream& operator << (ostream& out, vector<T>& t) { for (int i = 0; i < t.size(); i++) out << t[i] << " "; return out; }

int n, m;

void fill(vector<vint>& v)
{
	int sch = 1;
	for (auto& i : v)
	{
		for (auto& j : i)
		{
			j = sch++;
		}
	}
}

void solve1()
{
	bool is = n < m;
	if (n > m) swap(n, m);
	vector<vint> v(n, vint(m));
	fill(v);

	for (int i = 0; i < n; i++)
	{
		if (i % 2 == 1)continue;
		rotate(v[i].begin(), v[i].begin() + 2, v[i].end());
	}

	for (int i = 0; i < m; i++)
	{
		if (i % 2 == 1)continue;
		int l = v[n - 1][i];
		v[n - 1][i] = v[0][i];
		for (int j = n - 2; j >= 0; j--)
		{
			int t = v[j][i];
			v[j][i] = l;
			l = t;
		}
	}
	cout << "YES" << endl;
	if (is)
	{
		for (auto i : v)
		{
			cout << i << endl;
		}
	}
	else
	{
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < n; j++)
			{
				cout << v[j][i] << " ";
			}
			cout << endl;
		}
	}
		exit(0);
}

void solve2()
{
	bool is = n < m;
	if (n > m)swap(n, m);
	vint q(m);
	int i = 0;
	for (int r = 1; r <= m; r += 2)
	{
		q[i++] = r;
	}
	for (int r = 2; r <= m; r += 2)
	{
		q[i++] = r;
	}
	cout << "YES" << endl;
	if (is)cout << q << endl;
	else
	{
		for (int i : q)cout << i << endl;
}
	exit(0);
}

int main()
{
#ifdef _SANYA
	freopen("abc.txt", "r", stdin);
#else
#define T "lepus"
	//freopen(T ".in", "r", stdin);
	//freopen(T ".out", "w", stdout);
#endif
	cin >> n >> m;
	if (n == m && n == 1)return puts("YES\n1");
	if ((n >= 2 && m >= 4) || (m >= 2 && n >= 4))solve1();
	if ((n == 1 && (m == 2 || m == 3))
		|| (n == 2 && (m == 1 || m == 2 || m == 3))
		|| (m == 1 && (n == 2 || n == 3))
		|| (m == 2 && (n == 1 || n == 2 || n == 3)))return puts("NO");
	if (n == 3 && m == 3)
	{
		vector<vint> v = { {6,1,8}, {7,5,3}, {2,9,4} };
		cout << "YES" << endl;
		for (auto i : v)
		{
			cout << i << endl;
		}
		exit(0);
	}
	if (n == 1 && m == 4) return puts("YES\n2 4 1 3");
	if (n == 4 && m == 1) return puts("YES\n2\n4\n1\n3");
	if (n == 1 || m == 1)solve2();
	return 0;
}


#include <iostream>
#include <string.h>
#include <queue>
#include <cmath>
#include <vector>
#include <climits>
#include <set>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> ii;
typedef vector<vector<int>> Matrix;

const int maxN = 150, MOD = 1e9 + 7;
const ll INF = LLONG_MAX >> 1;

Matrix transp(const Matrix & v){
    Matrix ret(v[0].size(), vector<int>(v.size()));
    for(int i = 0; i < v.size(); i++){
        for(int j = 0; j < v[0].size(); j++){
            ret[j][i] = v[i][j];
        }
    }
    return ret;
}
void prt(const Matrix &c){
  for(int i = 0; i < c.size(); i++){
        for(int j = 0; j < c[i].size(); j++){
            cout << c[i][j] << '\t';
        }
        cout << '\n';
    }
}

const int seq[2][4] = {{1, 3, 0, 2}, {2, 0, 3, 1}};

Matrix solve(Matrix m){
    Matrix res;
    if(m.size() == 4){
        res = m;
        for(int i = 0; i < m[0].size(); i++){
          for(int j = 0; j < 4; j++)
            res[j][i] = m[seq[i & 1][j]][i];
        }
        return res;
    }
    for(int i = 0, L = ceil(m.size() / 2.0); i < L; i++){
        res.push_back(m[i]);
        if(i + L < m.size()) res.push_back(m[i + L]);
    }
    if(m.size() == 2 || m.size() == 3){
        int mtp = res[1][0];
        for(int i = 0; i + 1 < m[1].size(); i++) res[1][i] = res[1][i + 1];
        res[1].back() = mtp;
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    if(n == 1 && m == 1){
      cout << "YES\n1\n"; return 0;
    }
    if(n == 3 && m == 3){
        cout << "2 7 6\n9 5 1\n4 3 8\n"; return 0;
    }
    if(n <= 3 && m <= 3){
        cout << "NO\n";return 0;
    }
    Matrix c(n);
    for(int i = 0; i < n; i++){
        for(int j = 1; j <= m; j++){
            c[i].push_back(i * m + j);
        }
    }
    //prt(c);
    cout << "YES\n";
    if(n == 4){
      prt(solve(c));
      return 0;
    }
    else if(m == 4) {
      c = transp(c);
      c = solve(c);
      prt(transp(c));
      return 0;
    }
    for(int i = 0; i < 2; i++){
      c = solve(c);
      c = transp(c);
    }
    prt(c);
}


#include <iostream>
#include <string.h>
#include <queue>
#include <cmath>
#include <vector>
#include <climits>
#include <set>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> ii;
typedef vector<vector<int>> Matrix;

const int maxN = 150, MOD = 1e9 + 7;
const ll INF = LLONG_MAX >> 1;

Matrix transp(const Matrix & v){
    Matrix ret(v[0].size(), vector<int>(v.size()));
    for(int i = 0; i < v.size(); i++){
        for(int j = 0; j < v[0].size(); j++){
            ret[j][i] = v[i][j];
        }
    }
    return ret;
}
void prt(const Matrix &c){
  for(int i = 0; i < c.size(); i++){
        for(int j = 0; j < c[i].size(); j++){
            cout << c[i][j] << '\t';
        }
        cout << '\n';
    }
}

const int seq[2][4] = {{1, 3, 0, 2}, {2, 0, 3, 1}};

Matrix solve(Matrix m){
    Matrix res;
    if(m.size() == 4){
        res = m;
        for(int i = 0; i < m[0].size(); i++){
          for(int j = 0; j < 4; j++)
            res[j][i] = m[seq[i & 1][j]][i];
        }
        return res;
    }
    for(int i = 0, L = ceil(m.size() / 2.0); i < L; i++){
        res.push_back(m[i]);
        if(i + L < m.size()) res.push_back(m[i + L]);
    }
    if(m.size() == 2 || m.size() == 3){
        int mtp = res[1][0];
        for(int i = 0; i + 1 < m[1].size(); i++) res[1][i] = res[1][i + 1];
        res[1].back() = mtp;
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    if(n == 1 && m == 1){
      cout << "YES\n1\n"; return 0;
    }
    if(n == 3 && m == 3){
        cout << "YES\n2 7 6\n9 5 1\n4 3 8\n"; return 0;
    }
    if(n <= 3 && m <= 3){
        cout << "NO\n";return 0;
    }
    Matrix c(n);
    for(int i = 0; i < n; i++){
        for(int j = 1; j <= m; j++){
            c[i].push_back(i * m + j);
        }
    }
    //prt(c);
    cout << "YES\n";
    if(n == 4){
      prt(solve(c));
      return 0;
    }
    else if(m == 4) {
      c = transp(c);
      c = solve(c);
      prt(transp(c));
      return 0;
    }
    for(int i = 0; i < 2; i++){
      c = solve(c);
      c = transp(c);
    }
    prt(c);
}


#include <iostream>
#include <string.h>
#include <queue>
#include <cmath>
#include <vector>
#include <climits>
#include <set>

using namespace std;
typedef long long ll;
typedef pair<ll, ll> ii;
typedef vector<vector<int>> Matrix;

const int maxN = 150, MOD = 1e9 + 7;
const ll INF = LLONG_MAX >> 1;

Matrix transp(const Matrix & v){
    Matrix ret(v[0].size(), vector<int>(v.size()));
    for(int i = 0; i < v.size(); i++){
        for(int j = 0; j < v[0].size(); j++){
            ret[j][i] = v[i][j];
        }
    }
    return ret;
}
void prt(const Matrix &c){
  for(int i = 0; i < c.size(); i++){
        for(int j = 0; j < c[i].size(); j++){
            cout << c[i][j] << '\t';
        }
        cout << '\n';
    }
}

const int seq[2][4] = {{1, 3, 0, 2}, {2, 0, 3, 1}};

Matrix solve(Matrix m){
    Matrix res;
    if(m.size() == 4){
        res = m;
        for(int i = 0; i < m[0].size(); i++){
          for(int j = 0; j < 4; j++)
            res[j][i] = m[seq[i & 1][j]][i];
        }
        return res;
    }
    for(int i = 0, L = ceil(m.size() / 2.0); i < L; i++){
        res.push_back(m[i]);
        if(i + L < m.size()) res.push_back(m[i + L]);
    }
    if(m.size() == 2 || m.size() == 3){
        int mtp = res[1][0];
        for(int i = 0; i + 1 < m[1].size(); i++) res[1][i] = res[1][i + 1];
        res[1].back() = mtp;
    }
    return res;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int n, m;
    cin >> n >> m;
    if(n == 3 && m == 3){
        cout << "2 7 6\n9 5 1\n4 3 8\n"; return 0;
    }
    if(n <= 3 && m <= 3){
        cout << "NO\n";return 0;
    }
    Matrix c(n);
    for(int i = 0; i < n; i++){
        for(int j = 1; j <= m; j++){
            c[i].push_back(i * m + j);
        }
    }
    //prt(c);
    cout << "YES\n";
    if(n == 4){
      prt(solve(c));
      return 0;
    }
    else if(m == 4) {
      c = transp(c);
      c = solve(c);
      prt(transp(c));
      return 0;
    }
    for(int i = 0; i < 2; i++){
      c = solve(c);
      c = transp(c);
    }
    prt(c);
}


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

int main()
{
    srand(time(NULL));

    int n, m ; cin >> n >> m ; int grid[n][m] ;
    vector < int > orig, removed ;
    for(int i = 1; i <= n*m; i++)
        orig.push_back(i);

    set < int > neighbors ;

    for(int trial = 1; trial < 100; ++trial)
    {
        int cnt = 0;
        for(int i = 0; i < n ; i++)
        {
            cnt = 0;
            for(int j = 0; j < m and cnt <= 10; j++)
            {
                int sz = orig.size() ;
                int pos = rand() % sz ;
                int num = orig[pos] ;

                // cout << "SIZE = " << sz << " POSITION = " << pos << " CHOSEN = " << num << endl ;

                neighbors.clear();
                int ni = (num-1)/m , nj = num % m ; nj-- ; if(nj < 0) nj = m - 1 ;
                if(ni > 0) neighbors.insert(num-m);
                if(nj > 0) neighbors.insert(num-1);
                if(ni < (n-1)) neighbors.insert(num+m);
                if(nj < (m-1)) neighbors.insert(num+1);

                bool valid = true ;
                if(i > 0 )
                    valid &= neighbors.find(grid[i-1][j]) == neighbors.end();
                if(j > 0 )
                    valid &= neighbors.find(grid[i][j-1]) == neighbors.end();

                if(valid)
                {
                    grid[i][j] = num ;
                    swap(orig[pos], orig[sz-1]);
                    orig.pop_back();
                    removed.push_back(num);
                    cnt = 0;
                }
                else {
                    cnt++ , j-- ;
                }
            }
            if(cnt > 10) break ;
        }
        if(cnt <= 10)
        {
            // cout << "TRIALS REQUIRED = " << trial << endl ;
            cout << "YES" << endl ;
            for(int l = 0; l < n; l++)
            {
                for(int p = 0; p < m; p++)
                    cout << grid[l][p] << " " ;
                cout << endl ;
            }
            return 0;
        }
        else {
            for(auto x : removed)
                orig.push_back(x);
            removed.clear();
        }
    }
    cout << "NO" ;
    return 0;
}