#pragma comment (linker, "/STACK:20000000")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <queue>
#include <map>
#include <set>
#include <cmath>
#include <sstream>

#define pb push_back
#define mp make_pair
#define PI 3.14159265358979
#define sqr(x) (x)*(x)
#define forn(i, n) for(int i = 0; i < n; ++i)
#define ALL(x) x.begin(), x.end()
#define sz(x) int((x).size())
#define X first
#define Y second
typedef long long ll;
typedef long double ld;
using namespace std;
typedef pair<int,int> pii;
const int INF = 2147483647;
const ll LLINF = 9223372036854775807LL;
const int maxn = 1010;
int color[maxn][maxn] = {};
int curcol = 2;
const int dx[10] = {1,1,-1,-1,2,2,-2,-2};
const int dy[10] = {2,-2,2,-2,1,-1,1,-1};
int n, m;
int cnt[2*maxn*maxn] = {};
int main()
{
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#endif
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j) {
			/*if (color[i][j] == 0) dfs(i,j,curcol);*/
			if (color[i][j] == 0) {
				queue<pii> q;
				q.push(mp(i,j));
				color[i][j] = curcol;
				while (q.size()) {
					int tx = q.front().X;
					int ty = q.front().Y;
					q.pop();
					int rev = curcol;
					if (color[tx][ty] == curcol) rev++;
					for (int k = 0; k < 8; ++k) {
						int cx = tx + dx[k];
						int cy = ty + dy[k];
						if (cx>=0 && cx < n && cy >= 0 && cy < m && color[cx][cy] == 0) {
							color[cx][cy] = rev;
							q.push(mp(cx,cy));
						}
					}
				}
				curcol+=2;
			}

		}
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < m; ++j) cnt[color[i][j]]++;
	int ans = 0;
	for (int i = 0; i*2 <= curcol+10; ++i) {
		ans += max(cnt[i*2],cnt[i*2+1]);
	}
	printf("%d", ans);
	return 0;
}

//#include <bits/stdc++.h>
#include <bits/stdc++.h>
#include <string>
#include <stdio.h>
#include <string.h>
#define all(v)          v.begin(),v.end()
#define allr(v)         v.rbegin(),v.rend()
#define rep(i,m)        for(int i=0;i<m;i++)
#define REP(i,k,m)      for(int i=k;i<m;i++)
#define repd(i,m)        for(int i=m;i>=0;i--)
#define P(x)				cout<<#x<<" = { "<<x<<" }\n"
#define mem(a,b)        memset(a,b,sizeof(a))
#define mp              make_pair
#define pb              push_back
#define SORT(ptr , k )  sort ( ptr , ptr + k );
#define OO ((ll)1e12)
#define ooo -100000000
#define small  INT_MIN;
#define big  INT_MAX;
// #undef to remove macro
#include <cmath>
#include <complex>

using namespace std;
typedef long long ll;
typedef double db;
typedef long double   	  ld;
typedef vector<int>       vi;
typedef vector<bool>       vb;
typedef vector<double>    vd;
typedef vector< vi >      vvi;
typedef vector< vd >      vvd;
typedef vector<string>    vs;
typedef bitset<20> MASK;
//typedef  pair < int, string > point ;
#define mo 1000000007
#define INF 10000
#define sz(v)          ((int)((v).size()))
//std::ios_base::sync_with_stdio(false); means  i will not deal with c lang that will speed
const int oo = (int) 1e9;
const double eps = 1e-7;
#define md 1000000007
#define black 0;
#define white 1;
const int MAXN=1e5+10;
int dx[] = {1, 0, 0, -1, -1, -1, 1, 1};
int dy[] = {0, 1, -1, 0, 1, -1, 1, -1};
vi kmp ;

int main() {
//  cin.tie(0);
 // cin.sync_with_stdio(0);

 int n , m ;
 cin >> n >> m ;
 if (min( m , n  ) == 1 ){
    cout << max(m , n ) << endl;
 return 0 ;
 }

 if (min(n,m) == 2 ){
    int ans = (max(n , m )/4)*4;
    ans += min(max(n,m) %4 , 2)*2;
    cout << ans << endl;
    return 0 ;

 }

 if (m&1){
 int u = ceil(m / 2.0 );
 u *= ceil(n/2.0);
 u += ( m / 2 )*(n/2);
 cout << u << endl;

 return 0;
 }
 cout << n*m/2<<endl;

}

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include <stdlib.h>

#include <algorithm>
#include <vector>
#include <string>
#include <map>
using namespace std;

int cmp(const void *a, const void *b) {
	return (int*)a - (int*)b;
}

int steps[][2] = {
	{2,1},
	{2,-1},
	{1,2},
	{1,-2},
	{-2,1},
	{-2,-1},
	{-1,2},
	{-1,-2}
};

int n,m;

int f(int a, int b) {
	int r = 0;
	if(a % 2 == 0 || b % 2 == 0)
		return b * a / 2;
	return b * a / 2 + 1;
}

int main() {
	scanf("%d%d",&n,&m);
	int g = n / 3 + ((n % 3)? 1: 0);
	int v = m / 3 + ((m % 3)? 1: 0);

	if(n == 1) {
		printf("%d",m);
		return 0;
	}

	if(m == 1) {
		printf("%d",n);
		return 0;
	}

	if(n == 2 && m == 2) {
		printf("%d",n*m);
		return 0;
	}

	if(n == 2 && m == 3 || n == 3 && m == 2 ) {
		printf("%d",4);
		return 0;
	}

	if(n == 2 || m == 2) {
		if(n > m)
			n ^= m ^= n ^= m;
		printf("%d",m/4 * 4 + ((m % 4 == 3)? 2: m % 4) * 2);
		return 0;
	}

	printf("%d\n", max(max(g * m, v * n),f(n,m)));

	return 0;
}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(){
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);

	int n,m;

	cin>>n>>m;

	if(n>m)swap(n,m);

	if(n==1){cout<<m;return 0;}
	if(n==2 && m<=3){cout<<4;return 0;}

	int three=0;

	if(n==2)three=(m/4*2+min(m%4,2))*n;cerr<<three<<endl;

	int ans=n*m/2+(n*m)%2;
	cout<<max(three,ans);

}

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PI;
typedef long long LL;
typedef double D;
#define FI first
#define SE second
#define MP make_pair
#define PB push_back
#define R(I,N) for(int I=0;I<N;I++)
#define F(I,A,B) for(int I=A;I<B;I++)
#define FD(I,N) for(int I=N-1;I>=0;I--)
#define make(A) scanf("%d",&A)
#define make2(A,B) scanf("%d%d",&A,&B)
#define ALL(x) (x).begin(), (x).end()
#define db if(1)printf
template<typename C> void MA(C& a,C b){if(a<b)a=b;}
template<typename C> void MI(C& a,C b){if(a>b)a=b;}
int n,m;
main(){
  make2(n,m);
  if(n==1 || m==1)printf("%d\n",n*m);
  else{
    if(n == 2 || m == 2){
      int wyn = n*m/8 * 4;
      n%=4;
      m%=4;
      printf("%d\n",wyn + min(4,n*m));
    }else
      printf("%d\n",(n*m+1)/2);
  }
}

#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <vector>
#include <cmath>
#include <ctime>
#include <cassert>
#include <stack>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;

template<typename T> int size(T & a) { return (int) a.size(); }
template<typename T> T sqr(T a) {return a * a; }

#define pb push_back
#define mp make_pair
#define vi vector<int>
#define pii pair<int, int>
#define _(a, b) memset((a), (b), sizeof(a))
#define REP(i, a, b) for(int i=(a); i<(b); ++i)
#define all(a) a.begin(),a.end()

int dx[8] = {+2, +1, -1, -2, -2, -1, +1, +2};
int dy[8] = {-1, -2, -2, -1, +1, +2, +2, +1};

int t[1000][1000];
int mx[1000][1000];
int my[1000][1000];
int g[1000][1000];

int T = 0;
int n, m;
bool f(int x, int y) {
    return x >= 0 && x < m && y >= 0 && y < n;
}
bool dfs(int x, int y) {
    if (t[x][y] == T)
        return false;
    t[x][y] = T;
    REP(i, 0, 8) {
        if (f(x + dx[i], y + dy[i]) && mx[x+dx[i]][y+dy[i]]==-1) {
            mx[x+dx[i]][y+dy[i]] = x;
            my[x+dx[i]][y+dy[i]] = y;
            g[x][y] = 1;
            return true;
        }
    }
    REP(i, 0, 8) {
        if (f(x + dx[i], y + dy[i]) && dfs(mx[x+dx[i]][y+dy[i]], my[x+dx[i]][y+dy[i]])) {
            mx[x+dx[i]][y+dy[i]] = x;
            my[x+dx[i]][y+dy[i]] = y;
            g[x][y] = 1;
            return true;
        }
    }
    return false;
}
int main() {

    _(t,255);
    cin >> n >> m;

    int res= 0;
    _(mx, 255);
    _(my, 255);
    _(g,255);

    REP(i,0,n) REP(j,0,m)
        if ((i + j) % 2 == 0) {
            REP(u,0,8) {
                int nx=j+dx[u];
                int ny=i+dy[u];
                if (f(nx, ny) && mx[nx][ny] == -1 && g[j][i] == -1) {
                    g[j][i] = 1;
                    mx[nx][ny] = j;
                    my[nx][ny] = i;
                    ++res;
                    break;
                }
            }
        }
    REP(i,0,n) REP(j,0,m) if ((i + j) % 2 == 0 && g[j][i] == -1) {
        ++T;
        if (dfs(j, i)) ++ res;

    }
    cout << n*m-res;
#ifdef air
    printf("\n%.3lf\n", clock() * 1.0 / CLOCKS_PER_SEC);
#endif

}

#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 1005;

int n, m, num[N][N];

vector<int> edge[N * N];

void addedge(int u, int v) {
    edge[u].push_back(v);
}

int vis[N * N], stamp, match[N * N];

int stack[N * N], p[N * N], top;

bool find(int u) {
    top = 0, stack[top] = u, p[top] = 0;
    bool succ = false;
    while (top > -1) {
        int u = stack[top];
        if (succ) {
            match[edge[u][p[top] - 1]] = u;
            --top;
            continue;
        }
        if (p[top] == 0 && vis[u] == stamp || p[top] == edge[u].size()) {
            --top;
            continue;
        }
        vis[u] = stamp;
        int v = edge[u][p[top]++];
        if (match[v] == -1) {
            succ = true;
            match[v] = u;
            --top;
        } else {
            ++top;
            stack[top] = match[v];
            p[top] = 0;
        }
    }
    return succ;
}

const int dx[] = {1, -1, 1, -1, 2, -2, 2, -2},
          dy[] = {2, -2, -2, 2, 1, -1, -1, 1};

int main() {
    scanf("%d%d", &n, &m);
    int cnt0 = 0, cnt1 = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if ((i + j) % 2 == 0) {
                num[i][j] = cnt0++;
            } else {
                num[i][j] = cnt1++;
            }
        }
    }
    if (n > 10 && m > 10) {
        printf("%d\n", cnt0);
        return 0;
    }
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if ((i + j) % 2 == 0) {
                for (int d = 0; d < 8; ++d) {
                    int x = i + dx[d], y = j + dy[d];
                    if (x >= 0 && x < n && y >= 0 && y < m) {
                        addedge(num[i][j], num[x][y]);
                    }
                }
            }
        }
    }
    int ans = cnt0 + cnt1;
    memset(match, -1, sizeof(match));
    for (int i = 0; i < cnt0; ++i) {
        ++stamp;
        ans -= find(i);
    }
    printf("%d\n", ans);
    return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned int ui;
typedef pair < ll, ll > pll;
typedef pair < int, ll > pil;
typedef pair < ll, int > pli;
typedef pair < int, int > pii;
typedef unsigned long long ull;

#define F first
#define S second
#define en end()
#define bg begin()
#define rev reverse
#define mp make_pair
#define pb push_back
#define y1 y1234567890
#define um unordered_map
#define all(x) x.bg, x.en
#define sqr(x) ((x) * (x))
#define sz(x) (int)x.size()

const ll inf = (ll)1e18;
const ll mod = (ll)1e9 + 7;
const double pi = acos(-1.0);
const double eps = (double)1e-9;

const int dx[] = {0, 2, 1, 2, -1, -2, 1, -2, -1};
const int dy[] = {0, 1, 2, -1, 2, 1, -2, -1, -2};

const int N = 1005;

int n, m;

int main() {
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);

	//cin.tie(NULL);
	//cout.tie(NULL);
	//ios_base::sync_with_stdio(false);

	cin >> n >> m;

	if (n > m)
		swap(n, m);

	if (n == 1)
		cout << m;
	else if (n == 2)
		cout << (m / 4 * 2 + min(m % 4, 2)) * 2;
	else
		cout << (n * m + 1) / 2;

	return 0;
}

#if 1
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <functional>
#include <cstring>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <ctime>
#include <cassert>
#include <sstream>
#include <iostream>
#include <bitset>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int , int> pii;
typedef vector <int> veci;
typedef vector <veci> graph;
const LD eps = 1e-9;
const LD pi = acos(-1.0);

#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define iss istringstream
#define oss ostringstream
#define dbg(x) {cerr << #x << " = " << x << endl;}
#define dbgv(x) {cerr << #x << " ={"; for (int _i = 0; _i < x.size(); _i++) {if (_i) cerr << ", "; cerr << x[_i];} cerr << "}" << endl;}
#define NAME "problem"

int main()
{
	//freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout);
	//freopen(NAME ".in","r",stdin);freopen(NAME ".out","w",stdout);

	//for(int i = 0; i <= 5; ++i)
	//	for(int j = 0; j <= 5; ++j)
	//		if(i * i + j * j == 5)
	//			cout << i << " " << j << endl;
	int n, m;
	cin >> n >> m;
	if(n == 1 || m == 1)
		cout << max(n, m) << endl;
	else
	{
		if(n == 2 || m == 2)
		{
			int r = max(n, m);
			int w = r % 4;
			int ans = r / 4 * 4;

			ans += min(w, 2) * 2;
			cout << ans << endl;
		} else
		{
			int r1 = n * m / 2;
			int r2 = (n * m + 1) / 2;
			int res = max(r1, r2);
			cout << max(4, res) << endl;
		}
	}
	return 0;
}
/*************************
*************************/
#endif

#include <bits/stdc++.h>
using namespace std;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define FAST std::ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pi       acos(-1)
#define mp make_pair
#define pb push_back
#define ALL(v) v.begin(), v.end()
#define SORT(v) sort(ALL(v))
#define REVERSE(v) reverse(ALL(v))
#define F first
#define S second
#define ppb pop_back
#define GCD(m,n) __gcd(m,n)
#define LCM(m,n) (m*n)/GCD(m,n)
#define rep(i,a,n)  for(int i=a ; i<n ; i++)
#define repe(i,a,n) for(int i=a;i<=n;i++)
#define rev(i,a,b) for(int i=a;i>=b;i--)
////-------------------------------------------------------------------------
#define ld long double
#define int long long ////////////
////define ll long long
////--------------------------------------------------------------------------
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<vvvi> vvvvi;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<vvc> vvvc;
typedef vector<pii > vpii;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef map<int,int> mii;
typedef unordered_map<int,int> umii;
typedef map<char,int> mci;

struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);}

size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};

typedef unordered_map<int, int, custom_hash> safe_map;
typedef gp_hash_table<int, int, custom_hash> safe_hash_table;
////--------------------------------------------------------------------------
#define itv for(auto it= v.begin(); it != v.end(); ++it )
#define present(container, element) (container.find(element) != container.end())
#define cpresent(container, element) (find(ALL(container),element) != container.end())
#define   bs binary_search
#define  lb(v,val)  lower_bound(ALL(v), val)
#define  ub(v,val)  upper_bound(ALL(v), val)
#define Max(x,y,z) max(x,max(y,z))
#define Min(x,y,z) min(x,min(y,z))
#define maxc(v) *max_element(ALL(v))
#define minc(v) *min_element(ALL(v))
#define isvowel(a) (a=='a'||a=='e'||a=='i'||a=='o'||a=='u')
////--------------------------------------------------------------------------
 /*
#define dbg1(a) cout<<" *"<<a<<" ";
#define dbg2(a,b) cout<<" *"<<a<<" **"<<b<<" "     /////
#define dbg cout<<"move"
*/
#define nl "\n"
#define vin(v,n)   vi v(n); rep(i,0,n)  cin>>v[i]
#define dbg cerr <<"At line "<<__LINE__<<" move "<<nl
#define dbg1(x) cerr <<"At line "<<__LINE__<<" "<<#x<<"="<<x<<nl
#define dbg2(x,y) cerr <<"At line "<<__LINE__<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<nl
#define dbg3(x,y,z) cerr <<"At line "<<__LINE__<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<nl
#define prv(v)     rep(i,0,sz(v))  cerr<<v[i]<<" "; cerr<<endl
#define sz(s)         (int)((s).size())
#define coutsp(k)   cout<<setprecision(k)  //set precision (total length k icluding decimal and non decimal)
#define coutfsp(k)   cout<<fixed<<setprecision(k)  //fixed set precision(after decimal fixing)
#define trav(a, x) for(auto& a : x)
#define display(x) trav(a,x) cout<<a<<" ";cout<<endl
#define displaycerr(x) trav(a,x) cerr<<a<<" ";cerr<<endl

#define MOD 1000000007
#define POD 998244353
#define INF   (int)2e18   //------

const int N=201;

vi adj[N];

int vis[N]={};

int id=-1,mx=-1;

void dfs(int x,int y,int co)
{
  if(x==y)  return;
  vis[x]=1;

  if(co>=mx)
  {
    mx=co;
    id=x;
  }

  for(auto k: adj[x])
  {
     if(vis[k])
      continue;

    dfs(k,y,co+1);

  }

}

//-------------------------------------------------------------------------------
void do2win(int test)
{
  int n,m;  cin>>n>>m;

  int ans=0;

  int n1=min(n,m);
  int m1=max(n,m);

  if(n1==1)
  {
    ans+=m1;
  }
  else if(n1==2)
  {
    if(m1==2) ans+=4;
    else if(m1==3) ans+=4;
    else
    {
       ans+=4*(m1/4);
       if(m1%4==1) ans+=2;
       if(m1%4>=2)  ans+=4;
    }
  }
  else
   ans+=(n*m+1)/2;

 cout<<ans;

}
//-------------------------------------------------------------------------------

signed main()
{

   // #ifndef ONLINE_JUDGE
   //  freopen("input.txt", "r", stdin);
   //  freopen("output.txt", "w", stdout);
   //  freopen("error.txt","w", stderr);
   // #endif

   // #ifndef ONLINE_JUDGE
   //  cerr<<(1000*clock())/CLOCKS_PER_SEC<<"ms";
   // #endif

///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   FAST;
cout<<fixed<<setprecision(20);

///+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

   int test;  test=1;
///////---------------------------------|||||
            // cin>>test;        ////////>>>>>>>
////----------------------------------|||||

    for(int i=1;i<=test;i++)
    {
       // cout<<"Case #"<<i<<": ";

      do2win(i);
      cout<<nl;   //  IMPORTANT FOR NEXT LINE
    }

   return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
//int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
//int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
int dx[8]= {1,-1,2,-2,1,-1,2,-2};
int dy[8]= {2,2,1,1,-2,-2,-1,-1};
bool vis[1001][1001],vis2[1001][1001];
int n,m;
int bfs1(int i,int j,bool f)
{
    int ans=0;
    queue <pair<int,int> > q;
    q.push({i,j});
    vis[i][j]=1;
    if(f)ans++;
    int u,v;
    while(!q.empty())
    {
        int siz=q.size();
        f=!f;
        while(siz--)
        {
            u = q.front().first;
            v = q.front().second;
            //cerr<<u<<" "<<v<<" "<<f<<endl;
            q.pop();
            int x,y;
            for(int k=0 ; k<8 ; k++)
            {
                x=u+dx[k],y=v+dy[k];
                if(x>=0&&y>=0&&x<n&&y<m&&!vis[x][y])
                {
                    vis[x][y]=1;
                    q.push({x,y});
                    if(f)ans++;
                }
            }
        }
    }
    return ans;
}
int bfs2(int i,int j,bool f)
{
    int ans=0;
    queue <pair<int,int> > q;
    q.push({i,j});
    vis2[i][j]=1;
    if(f)ans++;
    int u,v;
    while(!q.empty())
    {
        int siz=q.size();
        f=!f;
        while(siz--)
        {
            u = q.front().first;
            v = q.front().second;
            //cerr<<u<<" "<<v<<" "<<f<<endl;
            q.pop();
            int x,y;
            for(int k=0 ; k<8 ; k++)
            {
                x=u+dx[k],y=v+dy[k];
                if(x>=0&&y>=0&&x<n&&y<m&&!vis2[x][y])
                {
                    vis2[x][y]=1;
                    q.push({x,y});
                    if(f)ans++;
                }
            }
        }
    }
    return ans;
}
int main()
{
    XsliferX();
    cin>>n>>m;
    int ans=0;
    int a,b;
    for(int i=0 ; i<n ; i++)
    {
        for(int j=0 ; j<m ; j++)
        {
            if(!vis[i][j])
            {
                a=bfs1(i,j,1);
                b=bfs2(i,j,0);
                ans+=max(a,b);
            }
        }
    }
    cout<<ans;
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);

#include <iostream>
#include <cstring>

using namespace std;

#define MAX_V1 1000000
#define MAX_V2 1000000
#define MAX_E 8000000

int V1 = 0,V2 = 0,l[MAX_V2],r[MAX_V1];
int E,to[MAX_E],next[MAX_E],last[MAX_V1];

void hk_init(){
    memset(last,-1,sizeof last);
}

void hk_add_edge(int u, int v){
    to[E] = v; next[E] = last[u]; last[u] = E++;
}

bool visited[MAX_V1];

bool hk_dfs(int u){
    if(visited[u]) return false;
    visited[u] = true;

    for(int e = last[u],v;e != -1;e = next[e]){
        v = to[e];

        if(l[v] == -1 || hk_dfs(l[v])){
            r[u] = v;
            l[v] = u;
            return true;
        }
    }

    return false;
}

int hk_match(){
    memset(l,-1,sizeof l);
    memset(r,-1,sizeof r);
    bool change = true;

    while(change){
        change = false;
        memset(visited,false,sizeof visited);

        for(int i = 0;i < V1;++i)
            if(r[i] == -1)
                change |= hk_dfs(i);
    }

    int ret = 0;

    for(int i = 0;i < V1;++i)
        if(r[i] != -1) ++ret;

    return ret;
}

int main(){
    int n,m;

    cin >> n >> m;

    int id[n][m];

    for(int i = 0;i < n;++i){
        for(int j = 0;j < m;++j){
            if((i + j) % 2 == 0) id[i][j] = V1++;
            else id[i][j] = V2++;
        }
    }

    int dr[] = {-1,-1,1,1,2,2,-2,-2};
    int dc[] = {-2,2,-2,2,-1,1,-1,1};
    hk_init();

    for(int i = 0;i < n;++i){
        for(int j = 0;j < m;++j){
            for(int k = 0;k < 8;++k){
                int r = i + dr[k],c = j + dc[k];

                if(r >= 0 && r < n && c >= 0 && c < m && (i + j) % 2 == 0)
                    hk_add_edge(id[i][j],id[r][c]);
            }
        }
    }

    cout << V1 + V2 - hk_match() << '\n';

    return 0;
}

/*
 * training.cpp
 *
 *  Created on: May 26, 2014
 *      Author: ghooo
 */

#include <cstring>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <complex>
#include <list>
#include <climits>
#include <cctype>
#include <bitset>
//#include <windows.h>

using namespace std;

#define pb push_back
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define sz(v) ((ll)v.size())
#define rep(i,m) for(int i=0;i<(int)(m);++i)
#define rep2(i,n,m) for(int i=n;i<(int)(m);i++)
#define For(it,c) for(__typeof(c.begin()) it=c.begin();it!=c.end();++it)
#define reset(a,b) memset(a,b,sizeof(a))
#define mp make_pair
#define dot(a,b) ((conj(a)*(b)).X)
#define X real()
#define Y imag()
#define length(V) (hypot((V).X,(V).Y))
#define vect(a,b) ((b)-(a))
#define cross(a,b) ((conj(a)*(b)).imag())
#define normalize(v) ((v)/length(v))
#define rotate(p,about,theta) ((p-about)*exp(point(0,theta))+about)
#define pointEqu(a,b) (comp(a.X,b.X)==0 && comp(a.Y,b.Y)==0)
#define clrq(x) while(!x.empty()) x.pop();
#define clrvv(v) rep(i,sz(v))v[i].clear();

typedef stringstream ss;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<pii> vpii;
typedef vector<string> vs;
typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<vector<int> > vii;
typedef long double ld;
typedef complex<double> point;
typedef pair<point, point> segment;
typedef pair<double, point> circle;
typedef vector<point> polygon;
typedef unsigned long long ull;
typedef long long ll;

//==============================================================
// handling triples
typedef pair<ll,pair<ll,ll> > triple;
#define tfirst first
#define tsecond second.first
#define tthird second.second
#define mt(x,y,z) mp(x,mp(y,z))
//---------------------------------------------------------------

const int oo = (int) 1e9;
const double PI = 2 * acos(0.0);
const double eps = 1e-9;
int main(){
	ios_base::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
#endif
	int n, m;
	cin >> n >> m;
	if(m>n) swap(n,m);
	int ret = (n*m+1)/2;
	if(m == 1) ret = n;
	if(m == 2){
		ret = (n)/4*4 + min((n)%4,2)*2;
	}
	cout << ret << endl;
	return 0;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <ctime>
#pragma comment (linker, "/STACK:256000000")

using namespace std;

const int maxN = 20;
int a[maxN][maxN], b[maxN][maxN];
int n, m, res;

bool valid(int x, int y) {
	return 0 <= x && x < n && 0 <= y && y < m;
}

int dx[] = {-2,-2,-1,-1, 1, 1, 2, 2};
int dy[] = {-1, 1,-2, 2,-2, 2,-1, 1};

void rec(int filled, int cnt) {
	if (filled == n * m) {
		res = max(res, cnt);
		return;
	}

	int x = filled / m;
	int y = filled % m;
	rec(filled + 1, cnt);
	if (b[x][y] == 0) {
		for (int i = 0; i < 8; ++i) {
			if (valid(x + dx[i], y + dy[i])) {
				++b[x + dx[i]][y + dy[i]];
			}
		}
		rec(filled + 1, cnt + 1);
		for (int i = 0; i < 8; ++i) {
			if (valid(x + dx[i], y + dy[i])) {
				--b[x + dx[i]][y + dy[i]];
			}
		}
	}
}

int main() {
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	cin >> n >> m;
	if (n > m) {
		swap(n, m);
	}
	if (n == 1) {
		cout << m << endl;
		return 0;
	}
	if (n == 2) {
		if (m % 4 == 2) {
			cout << 2 + m << endl;
		}
		if (m % 4 == 3 || m % 4 == 1) {
			cout << 1 + m << endl;
		}
		if (m % 4 == 0) {
			cout << m << endl;
		}
		return 0;
	}
	/*res = 0;
	rec(0, 0);
	cout << res << endl;*/

	int x = 0, y = 0;
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			if ((i + j) % 2 == 0) {
				++x;
			} else {
				++y;
			}
		}
	}

	cout << max(x, y) << endl;

	return 0;
}

#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <sstream>
#include <cstdlib>
#include <cassert>
#include <climits>
#include <complex>
#include <numeric>
#include <valarray>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;

#define inf 1061109567LL
#define pb push_back
#define mp make_pair
#define all(a) a.begin(),a.end()
#define mem(x,a) memset(x,a,sizeof(x))
#define rep(i,n) for(int i(0),_n(n);i<_n;++i)
#define repi(i,a,b) for(int i(a),_b(b);i<_b;++i)
#define repr(i,a,b) for(int i(a),_b(b);i>=_b;--i)
#define repe(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define len(x) ((int)(x.size()))

#define DEBUG 1
#if DEBUG && !ONLINE_JUDGE
	#define debug(args...) (Debugger()) , args
	class Debugger { public: Debugger(const std::string& _separator = ", ") : first(true), separator(_separator){} template<typename ObjectType> Debugger& operator , (const ObjectType& v) { if(!first) std::cerr << separator; std::cerr << v; first = false; return *this; } ~Debugger() { std::cerr << endl;} private: bool first; std::string separator; }; template <typename T1, typename T2> inline std::ostream& operator << (std::ostream& os, const std::pair<T1, T2>& p) { return os << "(" << p.first << ", " << p.second << ")"; } template<typename T> inline std::ostream &operator << (std::ostream & os,const std::vector<T>& v) { bool first = true; os << "["; for(unsigned int i = 0; i < v.size(); i++) { if(!first) os << ", "; os << v[i]; first = false; } return os << "]"; } template<typename T> inline std::ostream &operator << (std::ostream & os,const std::set<T>& v) { bool first = true; os << "["; for (typename std::set<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii) { if(!first) os << ", "; os << *ii; first = false; } return os << "]"; } template<typename T1, typename T2> inline std::ostream &operator << (std::ostream & os,const std::map<T1, T2>& v) { bool first = true; os << "["; for (typename std::map<T1, T2>::const_iterator ii = v.begin(); ii != v.end(); ++ii) { if(!first) os << ", "; os << *ii ; first = false; } return os << "]"; }
#else
		#define debug(args...)
#endif

int n,m,t1,t2;

int main(){
	ios_base::sync_with_stdio(0);

	cin>>t1>>t2;

	n=min(t1,t2);
	m=max(t1,t2);

	if(n==1){
		cout<<m;
		return 0;

	}

	if(n==2){

		cout<<2*(2*(m/4)+min(2,m%4));
		return 0;

	}

	cout<<(m/2+(m+1)/2)*(n/2)+(m+1)/2*(n%2);

}

#include<bits/stdc++.h>
using namespace std;
#define sd(x) scanf("%d",&x)
#define slld(x) scanf("%lld",&x)
#define ss(x) scanf("%s",x)
#define mod 1000000007
#define bitcount __builtin_popcountll
#define ll long long
#define pb push_back
#define pi pair<int,int>
#define pii pair<pi,int>
#define mp make_pair
int main()
{
	int i,j,k;
	int n,m;
	sd(n);
	sd(m);
	if(n==1||m==1)
		printf("%d\n",max(n,m) );
	else if(n==2||m==2)
	{
		int x=max(n,m);
		int y=x/2;
		int z=(y-y/2)*2;
		if(y%2==0&&x%2!=0)
			z++;
		printf("%d\n",z*2);
	}
	else
	{
		printf("%d\n",m*n-(m*n)/2 );
	}
	return 0;
}

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define repi(i, a, b) for(int i=(a); i>(b); i--)
#define db(x) (cerr << #x << ": " << (x) << '\n')
#define sync ios_base::sync_with_stdio(false), cin.tie(NULL)
#define iceil(n, x) (((n) + (x) - 1) / (x))
#define ll long long
#define gcd __gcd
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define sz size()
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vll vector<ll, ll>
#define vpii vector<pii>
#define vpll vector<pll>
#define vvi vector<vi>
#define fi first
#define se second
#define umap unordered_map
#define uset unordered_set
#define pqueue priority_queue
#define si(a) scanf("%d", &a)
#define sll(a) scanf("%lld", &a)
#define bitcount(x) __builtin_popcount(x)
#define cps CLOCKS_PER_SEC
#define PI acos(-1.0)
#define EPS 1e-9
#define mod 1000000007
#define MOD 1000000007
#define N 1005
using namespace std;

template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;

template<typename T>
using maxpq = priority_queue<T>;

//All indexing is 0-based
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,
       tree_order_statistics_node_update> ordered_set;
//methods: find_by_order(k); & order_of_key(k);
//To make it an ordered_multiset, use pairs of (value, time_of_insertion)
//to distinguish values which are similar.

//a and b are assumed to be taken modulo p
inline int add(int a, int b, int p = mod){ int c = a + b; if(c >= p) c -= p; return c;}
inline int sub(int a, int b, int p = mod){ int c = a - b; if(c < 0) c += p; return c;}
inline int mul(int a, int b, int p = mod){ return (a * 1ll * b) % p;}

int dx[] = {1, 1, -1, -1, 2, 2, -2, -2};
int dy[] = {2, -2, 2, -2, 1, -1, 1, -1};

int n,m;
bool grid[N][N];

//Returns distance between (a, b) and (c, d)
inline double dist(double a, double b, int c, int d) {
  return sqrt(pow(a - c, 2) + pow(b - d, 2));
}

//Returns true if no knight at (u, v)
inline bool check(int u, int v) {
  return u < 0 || v < 0 || u > n || v > m || grid[u][v] == 0;
}

main()
{
  #ifdef CP
    freopen("/home/tarun/Desktop/input.txt", "r", stdin);
    //freopen("/home/tarun/Desktop/output.txt", "w", stdout);
  #endif
  sync;
  clock_t clk = clock();
  cerr << "I will return...\n";

  cin >> n >> m;
  if(m > n) swap(m, n);

  if(m == 1) cout << n << '\n';
  else if(m == 2) {
    cout << 2 * (iceil(n, 4) + iceil(n-1, 4)) << '\n';
  }
  else if(n * m % 2) {
    cout << (n * m + 1) / 2 << '\n';
  }
  else cout << n * m / 2 << '\n';

  cerr << "...don't you ever hang your head.\n";
  cerr << "Time (in ms): " << double(clock() - clk) * 1000.0 / cps << '\n';
}

//Compile using:
//g++ -o filename.exe --std=c++11 filename.cpp
//Use -D CP for defining a macro CP in the local environment

/* ID: AnilKishore ( RedAnt ) */

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>

#include <iostream>
#include <algorithm>
#include <string>

#include <vector>
#include <set>
#include <map>
#include <queue>

using namespace std;

typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PI;

#define PB(x) push_back(x)
#define MP(x,y) make_pair(x,y)
#define F first
#define S second
#define SET(v,x) memset(v,x,sizeof v)
#define FOR(i,a,b) for(int _n(b),i(a);i<_n;i++)
#define EACH(it,v) for(typeof((v).begin()) it = (v).begin();it!=(v).end();it++)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
#define SORT(v) sort(ALL(v))
#define SZ(v) int(v.size())
#define SI ({int x;scanf("%d",&x);x;})

#define MX 100005

int g(int n)
{
	int r = (n/4)*4;
	if(n%4==1) r+=2;
	else if(n%4>1) r+=4;
	return r;
}

int f(int R,int C)
{
	int r = (C+1)/2, c = C/2;
	r = (R/2)*(r+c) + ((R%2)?r:0);
	return max(r,R*C-r);
}

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

	int n = SI, m = SI, r = 0;

	if(n==1 || m==1) r = m*n;
	else if(n==2||m==2) r = g(max(n,m));
	else r = max(f(n,m),f(m,n));

	printf("%d\n",r);

	return 0;
}

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
using namespace std;
typedef long long ll;

int main(){
  #ifdef twentyone
  freopen("B.in","r",stdin);
  #endif

  ll n,m; cin>>n>>m;
  if (n<m) swap(n,m);
  ll res=(n*m+1)/2ll;
  if (n<=2 and m<=2 or m==1 or n==1) res=n*m;
  if (n==3 and m==2) res=4ll;

  if (m==2){
    res=max(res,2*(2*(n/4)+min(n%4,2ll)));
  }

  cout<<res<<endl;
}

/*
その花を　咲かせば
あとは
枯れるのが　その定めか

その命　散らして
つなぐ
思いを全て　受け取って
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <cstdlib>
#include <utility>
#include <cmath>
using namespace std;
#define ll long long
#define all(x) (x).begin(), (x).end()
#define ayacin ios::sync_with_stdio(false);
#define mod 1000000007
#define yukari 999999999
#define M_PI12 3.141592653
#define Parseedouble long double
#define N 40005
#define lson o<<1
#define rson o<<1|1
int main(){
	ll m,n;
	cin>>n>>m;
    if(n<m) swap(n,m);
    if(m==1) cout<<n;
    if(m==2)
	switch(n%4){
        case 0:cout<<n<<endl; break;
        case 1:cout<<n+1<<endl; break;
        case 2:cout<<n+2<<endl; break;
        case 3:cout<<n+1<<endl; break;
    }
    if(m>2) cout<<(n*m+1)/2<<endl;
}

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

int ptr[2];
int idx[1005][1005];

struct BipartiteMatching {
	int n, m;
	vector<vector<int>> graph;
	vector<int> matched, match, edgeview, level;
	vector<int> reached[2];
	BipartiteMatching(int n, int m) : n(n), m(m), graph(n), matched(m, -1),
		match(n, -1) {}
	bool assignLevel() {
		bool reachable = false;
		level.assign(n, -1);
		reached[0].assign(n, 0);
		reached[1].assign(m, 0);
		queue<int> q;
		for (int i = 0; i < n; i++) {
			if (match[i] == -1) {
				level[i] = 0;
				reached[0][i] = 1;
				q.push(i);
			}
		}
		while (!q.empty()) {
			auto cur = q.front(); q.pop();
			for (auto adj : graph[cur]) {
				reached[1][adj] = 1;
				auto next = matched[adj];
				if (next == -1) {
					reachable = true;
				}
				else if (level[next] == -1) {
					level[next] = level[cur] + 1;
					reached[0][next] = 1;
					q.push(next);
				}
			}
		}
		return reachable;
	}
	int findpath(int nod) {
		for (int &i = edgeview[nod]; i < graph[nod].size(); i++) {
			int adj = graph[nod][i];
			int next = matched[adj];
			if (next >= 0 && level[next] != level[nod] + 1) continue;
			if (next == -1 || findpath(next)) {
				match[nod] = adj;
				matched[adj] = nod;
				return 1;
			}
		}
		return 0;
	}
	int solve() {
		int ans = 0;
		while (assignLevel()) {
			edgeview.assign(n, 0);
			for (int i = 0; i < n; i++)
				if (match[i] == -1)
					ans += findpath(i);
		}
		return ans;
	}
};

int dr[8][2] =
{
	2,-1,2,1,-2,1,-2,-1,
	1,2,1,-2,-1,2,-1,-2
};

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);

	if (n <= 100 || m <= 100)
	{
		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				idx[i][j] = ptr[(i + j) & 1]++;
			}
		}

		BipartiteMatching bm{ ptr[0], ptr[1] };

		for (int i = 0; i < n; i++)
		{
			for (int j = 0; j < m; j++)
			{
				if ((i + j) & 1) continue;
				for (int k = 0; k < 8; k++)
				{
					int nx = i + dr[k][0], ny = j + dr[k][1];
					if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
					bm.graph[idx[i][j]].push_back(idx[nx][ny]);
				}
			}
		}

		printf("%d\n", n * m - bm.solve());
	}
	else
	{
		printf("%d\n", (n * m + 1) / 2);
	}
}

// Anve$hi $hukla
// Until the lion learns how to write, every story will glorify the hunter.

#include <bits/stdc++.h>
using namespace std;
#define WHITE 0
#define BLACK 1
#define TRACE
#ifdef TRACE
#define trace1(x)       cerr<< #x <<": "<<x<<endl;
#define trace2(x, y)    cerr<< #x <<": "<<x<<" | "<< #y <<": "<<y<< endl;
#define trace3(x, y, z) cerr<< #x <<": "<<x<<" | "<< #y <<": "<<y<<" | "<< #z <<": "<<z<< endl;
#else
#define trace1(x)
#define trace2(x, y)
#define trace3(x, y, z)
#endif

typedef long long LL;

typedef vector<int> VI;
typedef vector<VI> VVI;
bool FindMatch(int i, const VVI &w, VI &mr, VI &mc, VI &seen) {
  for (int j = 0; j < w[i].size(); j++) {
    if (w[i][j] && !seen[j]) {
      seen[j] = true;
      if (mc[j] < 0 || FindMatch(mc[j], w, mr, mc, seen)) {
        mr[i] = j;
        mc[j] = i;
        return true;
      }
    }
  }
  return false;
}

int BipartiteMatching(const VVI &w, VI &mr, VI &mc) {
  mr = VI(w.size(), -1);
  mc = VI(w[0].size(), -1);

  int ct = 0;
  for (int i = 0; i < w.size(); i++) {
    VI seen(w[0].size());
    if (FindMatch(i, w, mr, mc, seen)) ct++;
  }
  return ct;
}
const int Maxn = 1005;
int Board[Maxn][Maxn];
int N,M,cntW,cntB;

const int dx[] = {2, 2, 1, 1, -2, -2, -1, -1};
const int dy[] = {1, -1, 2, -2, 1, -1, 2, -2};

void dfs(int x,int y){
  for(int i=0;i<8;i++){
    int nextX = x+dx[i];
    int nextY = y+dy[i];
    if(nextX>=0 && nextY>=0 && nextX<N && nextY<M && Board[nextX][nextY]==-1){
      Board[nextX][nextY] = 1 - Board[x][y];
      if(Board[nextX][nextY]==WHITE)
        cntW++;
      else
       cntB++;
      dfs(nextX, nextY);
    }
  }
  return;
}

int main(){
  int Ans=0;
  cin >> N >> M;
  memset(Board,-1,sizeof(Board));
  for(int i=0;i<N;i++){
    for(int j=0;j<M;j++){
      if(Board[i][j] == -1){
        Board[i][j] = WHITE;
        cntW = 1, cntB = 0;
        dfs(i,j);
        Ans += max(cntB,cntW);
      }
    }
  }
  cout << Ans << endl;
  return 0;
}

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

int main()
{
    int n,m,z;
    scanf("%d%d",&n,&m);
    if(n>m)
        z=n,n=m,m=z;
    if(n==1)
        cout<<m;
    else if(n==2)
    {
        if(m%4==0)
            cout<<m;
        else if(m%4==1)
            cout<<m/4*4+2;
        else if(m%4==2)
            cout<<m/4*4+4;
        else cout<<m/4*4+4;
    }
    else cout<<(n*m+1)/2;
    return 0;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

int xx[4] = {0,1,2,2};
int main()
{
    int n, m;
    while(scanf("%d %d", &n, &m) != EOF)
    {
        if(n == 1 || m == 1)
        {
            printf("%d\n", n * m);
        }
        else
        {
            if(n == 2 || m == 2)
            {
                int x = (n > m? n : m);
                x = x / 4 * 2 + xx[x % 4];
                printf("%d\n", 2 * x);
            }
            else{
                printf("%d\n", (n * m + 1) / 2);
            }
        }
    }
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    if(n>m) swap(n,m);
    if(n==1) printf("%d",m);
    else if(n==2){
        int ans=0;
        if(m%4>=3) ans+=4;
        else ans+=2*(m%4);
        ans+=m/4*4;
        printf("%d\n",ans);
    }
    else printf("%d\n",n*m-n*m/2);
    return 0;
}

//
//  Created by Henry Cafaro
//  Copyright © 2020 Henry Cafaro. All rights reserved.
//

# include <iostream>
# include <string>
# include <vector>
# include <algorithm>
# include <bitset>
# include <queue>
# include <cstring>

#define ll long long

using namespace std;

int n,m;

int round(int q){
    if(q%2 == 0) return q/2;

    return (q+1)/2;

}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m;

    if(n==1) {cout << m << endl; return 0;}
    if(m==1) {cout << n << endl; return 0;}

    if(n==2){
        if(m%4 == 1){
            cout << 4*(m-1)/4 + 2 << endl;
            return 0;
        }
        if(m%4 == 2){
            cout << 4*(m-2)/4 + 4<< endl;
            return 0;
        }
        if(m%4 == 3){
            cout << 4*(m-3)/4 + 4<< endl;
            return 0;
        }

        cout << m << endl;
        return 0;
    }

    if(m==2){
        if(n%4 == 1){
            cout << 4*(n-1)/4 + 2 << endl;
            return 0;
        }
        if(n%4 == 2){
            cout << 4*(n-2)/4 + 4<< endl;
            return 0;
        }
        if(n%4 == 3){
            cout << 4*(n-3)/4 + 4<< endl;
            return 0;
        }

        cout << n << endl;
        return 0;
    }

    cout << round(n*m) << endl;

}

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define IOS {ios :: sync_with_stdio(false); cin.tie(0);cout.tie(0); }
#define F first
#define S second
#define pb push_back
typedef long double ld;
#define deci(n) cout << fixed << setprecision(n);
typedef long long ll;
#define all(a) a.begin(), a.end()
#define pll pair<ll, ll>
#define bits(x) __builtin_popcount(x)
#define fori(n)  for (ll i = 0; i < n; i++)
#define fori2(n) for(ll i=1;i<=n;i++)
#define forj(n)  for (ll j = 0; j < n; j++)
#define forj2(n) for(ll j=1;j<=n;j++)
#define fork(n)  for (ll k = 0; k < n; k++)
#define fork2(n) for(ll k=1;k<=n;k++)
#define vll vector <ll>
#define mll map <ll, ll>
#define vpll vector <pll>
ll md;

#define BSET(a, p) ((a) | (1ll << (p)))
#define BCHK(a, p) ((a) & (1ll << (p)))
#define BXOR(a, p) ((a) ^ (1ll << (p)));
#define BREM(a, p) (BCHK(a, p)?(BXOR(a, p)):(a))
#define BSHO(a, N) (bitset<N>(a))
// const ll N = 100005;
// ll fac[N] = {1};
// #define calfac for(ll i=1  ;i<N;i++) fac[i] = (fac[i-1]*i)%md;
// ll C[N+1][M+1];
// void  ncr(){
//     ll n = N,k = M;
//     for (ll i = 0; i <= n; i++) {
//         for (ll j = 0; j <= min(i, k); j++) {
//             if (j == 0 || j == i)  C[i][j] = 1;
//             else C[i][j] = C[i - 1][j - 1] +  C[i - 1][j];
//         }
//     }
// }

#define RBTTYPE int
#define ordered_set tree<RBTTYPE, null_type, less<RBTTYPE>, rb_tree_tag,tree_order_statistics_node_update>

ll modexp(ll x, ll ex) {
    ll ans = 1ll;
    while (ex > 0) {
        if (ex & 1ll) ans = (ans * x) % md;
        ex >>= 1ll;
        x = (x * x) % md;
    }
    return ans;
}
ll modInv(ll a)
{
    return pow(a,md-2);
}

// ll nCr(ll n,ll r)
// {
//     return (fac[n]*modInv((fac[r]*fac[n-r])%md))%md;
// }

ll po(ll x,ll n){
    if(n==0) return 1;
    if(n%2==1) return (x*po(x,n-1))%md;
    else {
        ll k=po(x,n/2)%md;
        return (k*k)%md;
    }
}

ll gcd(ll x, ll y) {
    if (x < y) return gcd(y, x);
    if (y == 0) return x;
    return gcd(y, x % y);
}
 #define int ll
// Function to return the maximum number of
// knights that can be placed on the given
// chessboard such that no two
// knights attack each other
int max_knight(int n, int m)
{

    // Check for corner case #1
    // If row or column is 1
    if (m == 1 || n == 1) {

        // If yes, then simply print total blocks
        // which will be the max of row or column
        return max(m, n);
    }

    // Check for corner case #2
    // If row or column is 2
    else if (m == 2 || n == 2) {

        // If yes, then simply calculate
        // consecutive 2 rows or columns
        int c = 0;
        c = (max(m, n) / 4) * 4;

        if (max(m, n) % 4 == 1) {
            c += 2;
        }
        else if (max(m, n) % 4 > 1) {
            c += 4;
        }
        return c;
    }

    // For general case, just print the
    // half of total blocks
    else {
        return (((m * n) + 1) / 2);
    }
}

// Driver code
int32_t main()
{
    ll i,j,k,n,m;

    cin >> n >> m;
    cout << max_knight(n, m)<<"\n";

    return 0;
}

#include <iostream>
using namespace std;

int main() {
    // your code goes here
    int m,n,answer;
    cin>>m>>n;
    if(m==1)answer=n;
    else if(n==1)answer=m;
    else if((m*n)%2==0){
        if(m==2&&n==2){
            answer=4;
        }
        else if(m==2&&n!=2){
            if(n%4==1)answer = (m*n+2)/2;
            else if(n%4==2)answer = (m*n+4)/2;
            else if(n%4==3)answer = (m*(n-1)+4)/2;
            else answer = (m*n)/2;
        }
        else if(m!=2&&n==2){
            if(m%4==1)answer = (m*n+2)/2;
            else if(m%4==2)answer = (m*n+4)/2;
            else if(m%4==3)answer = ((m-1)*n + 4)/2;
            else answer = (m*n)/2;
        }
        else answer = (m*n)/2;
    }
    else if((m*n)%2==1)answer = (m*n + 1)/2;
    cout<<answer;
    return 0;
}

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

int n, m;

int main() {
	ios::sync_with_stdio(false), cin.tie(0);
	cin >> n >> m;
	if(n > m)
		swap(n, m);
	if(n == 1)
		cout << m;
	else if(n == 2 && m % 2)
		cout << m + 1;
	else if(n == 2 && m % 4 == 2)
		cout << m + 2;
	else
		cout << (n * m + 1) / 2;
	return 0;
}

#include <cstdio>
#include <cstring>
#include <algorithm>
const int dx[] = {1, 1, 2, 2, -1, -1, -2, -2};
const int dy[] = {2, -2, 1, -1, 2, -2, 1, -1};
const int N = 4;
bool vis[N][N];
int r, c, ans;

void dfs(int x, int y, int tot) {
	if (tot > ans)
		ans = tot;
	if (x == r + 1)
		return ;
	int nx, ny, f = true;
	for (int i = 0; i < 8; ++i) {
		nx = x + dx[i];
		ny = y + dy[i];
		if (nx >= 1 && nx <= r && ny >= 1 && ny <= c && vis[nx][ny]) {
			f = false;
			break;
		}
	}
	if (f) {
		vis[x][y] = true;
		if (y == c)
			dfs(x + 1, 1, tot + 1);
		else
			dfs(x, y + 1, tot + 1);
		vis[x][y] = false;
	}

	if (y == c)
		dfs(x + 1, 1, tot);
	else
		dfs(x, y + 1, tot);
}

int main() {
	scanf("%d%d", &r, &c);
	if (1 == r || 1 == c)
		printf("%d\n", std::max(r, c));
	else if (r == 2 || c == 2) {
		if (2 == c)
			std::swap(r, c);
		int g = c % 4;
		ans = r * (c - g) / 2;
		if (g <= 2)
			ans += g * 2;
		else
			ans += 4;
		printf("%d\n", ans);
	} else if (r >= 4 || c >= 4) {
		ans = (r * c + 1) / 2;
		printf("%d\n", ans);
	} else {
		ans = 0;
		dfs(1, 1, 0);
		printf("%d\n", ans);
	}
	return 0;
}

#include<bits/stdc++.h>
#define ll long long int
#define N 1010
using namespace std;

int main()
{
    int n,m;
    cin>>n>>m;
    if(n==1 || m==1) printf("%d\n",n*m);
    else if(n==2) printf("%d\n",4*(m/4)+2*min(m%4,2));
    else if(m==2) printf("%d\n",4*(n/4)+2*min(n%4,2));
    else if(n==3 && m==3) printf("5\n");
    else if((n==3 && m==5)||(n==5 && m==3)) printf("8\n");
    else if((n==3 && m==6)||(n==6 && m==3)) printf("9\n");
    else if(n==4 && m==4) printf("8\n");
    else printf("%d\n",m*n-(m*n)/2);
    return 0;
}

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0; i<n; i++)
#define repa(i,a,b,d) for(int i=a; i<=b; i+=d)
#define repd(i,a,b,d) for(int i=a; i>=b; i-=d)
#define repi(it,stl) for(auto it = (stl).begin(); (it)!=stl.end(); ++(it))
#define sz(a) ((int)(a).size())
#define mem(a,n) memset((a), (n), sizeof(a))
#define all(n) (n).begin(),(n).end()
#define mp(a,b) make_pair((a),(b))
#define pii pair<int,int>
#define vi vector<int>
#define vs vector<string>
#define sstr stringstream
#define myfind(v,x) (find(all((v)),(x))-(v).begin())

typedef long long ll;
using namespace std;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
#ifndef ONLINE_JUDGE
    freopen("main.txt","rt",stdin);
    //  freopen("out.txt","wt",stdout);
#endif
    int n,m;
    cin >> n >> m;
    if(n > m) swap(n,m);
    if(n == 1){
        cout << m;
        return 0;
    }
    if(n==2){
        //**..**..**
        //**..**..**
        int n1 = 2*(m/4) + min(2,m%4);
        cout << 2*n1;
        return 0;
    }
    //*.*.*.*.
    //.*.*.*.*
    //*.*.*.*.
    int n1 = (m+1)/2, n2 = m/2;
    int res = n1*((n+1)/2) + n2*(n/2);
    cout << res;

    return 0;
}

#include<cstdio>
#include<cstring>
int n,m;
int main()
{
	scanf("%d %d",&n,&m);
	int ans;
	if(n==1||m==1)
		ans=n*m;
	else if(n==2)
		ans=m/4*4+(m%4>1?4:m%4*2);
	else if(m==2)
		ans=n/4*4+(n%4>1?4:n%4*2);
	else
		ans=(n*m+1)/2;
	printf("%d\n",ans);
	return 0;
}

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

typedef long long ll;

ll n, m, ans;
int T;

int main() {
	T = 1;
	while(T--) {
		scanf("%lld %lld", &n, &m);
		if(n > m) swap(n, m);
		if(n == 1) ans = m;
		else if(n == 2) {
			ll t = m / 4;
			ans = t * 4;
			ll a = 2, b = m - ans, minn = min(a, b);
			ans += (minn << 1);
		}
		else {
			ll a = n / 2, b = m / 2;
			ans = a * b + (n - a) * (m - b);
		}
		printf("%lld\n", ans);
	}
	return 0;
}

#include<bits/stdc++.h>

int main()
{
    int p=1,row,col,tc;
    //scanf("%d",&tc);
    //while(tc--)
    //{
        scanf("%d %d",&row,&col);
        if(row==1||col==1)
        {
            if(row==1)printf("%d\n",col);
            else printf("%d\n",row);
            return 0;
            //continue;
        }
        if(row==2||col==2)
        {
            int t=0,counti=0,a=0;
            while(t<row*col)
            {
                t++;
                counti++;
                a++;
                if(t%4==0)
                {
                    while(a--)t++;
                    a++;
                }
            }
            printf("%d\n",counti);
            return 0;
            //continue;
        }
        if((row*col)&1)printf("%d\n",(row*col)/2+1);
        else printf("%d\n",(row*col)/2);
    //}
    return 0;
}

#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
long n,m,ans;
int main()
{
	 ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
	cin>>n>>m;

    if (m>n)
    {
    	int x=m;
    	m=n;
    	n=x;
	}
	if (m==1) cout<<n<<endl;
	else
	{
		if (m==2)
		{
			ans=4*(n/4);
			if (n%4>=2)ans+=4;
			else
			ans+=2*(n%4);
			cout<<ans;
		}
		else
		{
			ans=n*m/2 + (n*m )% 2;
			cout<<ans<<endl;
		}
	}
}

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

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

#define INF (INT_MAX / 2)
#define endl '\n'

#define MAX_N 1001

int n, m;

int main() {
	ios_base::sync_with_stdio(false); cin.tie(NULL);

	cin >> n >> m;
	if (n > m)
		swap(n, m);

	if (n == 1)
		cout << max(n, m) << endl;
	else if (n == 2)
		cout << m / 4 * 4 + min(m % 4, 2) * 2 << endl;
	else
		cout << (n * m + 1) / 2 << endl;

	return 0;
}

#include<bits/stdc++.h>
using namespace std;
int n, m;

int main() {
	scanf("%d%d", &n, &m);
	if(n > m) swap(n, m);
	if(n == 1) printf("%d\n", m);
	else if(n == 2 && m <= 2) printf("%d\n", n * m);
	else if(n == 2) {
		if(m % 4 == 0) printf("%d\n", n * m / 2);
		else if(m % 4 == 2) printf("%d\n", n * m / 2 + 2);
		else printf("%d\n", n * m / 2 + 1);
	}
	else printf("%d\n", n * m - n * m / 2);
}

#include <iostream>
#include <fstream>
#include <string>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#define y1 aasdfasdfasdf
#define yn askfhwqriuperikldjk
#define INF 1000000000
#define eps 1e-15
//#define M_PI 3.141592653589793
//#define mx 1000000000000ll
#define bs 1000000007
//#define szz 400
using namespace std;
long long n,m,p,ans,e;
int main(){
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
cin>>n>>m;
if (m==1||n==1)ans=max(m,n);
else if (m==2||n==2)
{p=max(m,n);e=p/4;ans=4*e;p%=4;if (p<3)ans+=2*p; else ans+=4;
 }
else ans=(m*n+1)/2;
cout<<ans<<endl;
cin.get();cin.get();
return 0;}

#include<bits/stdc++.h>
using namespace std;
int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,m;
	cin>>n>>m;
	if(n==1 || m==1) cout<<max(n,m);
	else if(n==2) cout<<m+(m&1?1:(m%4));
	else if(m==2) cout<<n+(n&1?1:n%4);
	else cout<<(int)(ceil(n*m/2.0));
}

#include<bits/stdc++.h>
#define in freopen("input.txt","r",stdin)
#define out freopen("output.txt","w",stdout)

#define inp freopen(".in","r",stdin)
#define outp freopen(".out","w",stdout)

using namespace std;

#define pb push_back
#define pf push_front
#define p_f pop_front
#define p_b pop_back
#define LL long long int
#define LD long double
#define MP make_pair
#define sqr(x) (x*x)
#define fi first
#define dist(x,y,xx,yy) sqrt( (x-xx)*(x-xx)+(y-yy)*(y-yy) )
#define lenint int intsi(int x){ int cnt=0; while(x>0){cnt++;x/=10;} return (cnt); }
#define se second
#define all(v) v.begin(),v.end()
#define sc scanf
#define DEBUG(a) cout<<#a<<" -> "<<a<<endl;
#define pr printf
#define si size()
#define str strlen
#define time clock()/(double)CLOCKS_PER_SEC
#define gcd LL GCD(LL a,LL b){ if(b==0)return a;else return GCD(b,a%b); }
const int INF=(-1u)/2;
const long long int INF2=(-1ull)/2;
int a,b,i,d[1011000],j,k,n,m,timer=0,l,r,x,y;
int c[1011000],cnt=0,fl=0,a2,a3=-1000000,ans=0;
main()
{
    #ifndef ONLINE_JUDGE
        in;out;
    #endif
    ios_base::sync_with_stdio(0);
    cin>>n>>m;
    if( n>m )swap(n,m);
    if( n==1 )
    {
        cout<<m<<endl;
    }
    else if( n==2 )
    {
        cout<<2*(2*(m/4)+min( m%4,2 ))<<endl;
    }
    else
    {
        cout<<(n*m+1)/2<<endl;
    }
    return 0;
}

// practice with Dukkha, coached by rainboy
#include <algorithm>
#include <iostream>

using namespace std;

int main() {
	int n, m; cin >> n >> m;
	if (n > m)
		swap(n, m);
	int ans;
	if (n == 1)
		ans = m;
	else if (n == 2)
		ans = m / 4 * 4 + min(m % 4, 2) * 2;
	else
		ans = (n * m + 1) / 2;
	cout << ans << '\n';
	return 0;
}

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <set>
#include <vector>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <map>
#include <queue>
#include <deque>
#include <bitset>

#define y0 y63475625
#define y1 y28435
#define j0 jfd0sf
#define j1 je90ue0
#define sqr(x) ((x)*(x))
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define re return
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqrt(x) (sqrt(abs(x)))
#define fill(a, x) memset(a, x, sizeof(a))

using namespace std;

typedef vector <int> vi;
typedef vector <vi> vvi;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> ii;
typedef vector <ii> vii;
typedef double D;
typedef pair <ll, ll> pll;
typedef vector <string> vs;

template <class T> T abs(const T a) {
    return a > 0 ? a : -a;
}

const double PI = 2.0 * acos(1.0);

int n;
int m;

int main()
{
    cin >> n >> m;
    if (n > m)
        swap(n, m);
    if (n == 2) {
        int ans = 0;
        rep(i, m) {
            cerr << i << ' ' << i % 4 << endl;
            if (i % 4 < 2)
                ans += 2;
        }
        cout << ans << endl;
        re 0;
    }
    if (n == 1) {
        cout << n * m << endl;
        re 0;
    }
    cout << (n * m + 1) / 2 << endl;
    return 0;
}

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<vector<int> > vvi;
typedef vector<pii> vii;
typedef vector<vector<pii> > vvii;
typedef long double ld;
typedef map<int, int> mapii;
typedef map<string, int> mapsi;

#define erep(i, x, n) for (auto i = x; i<=(ll)(n); i++)
#define rep(i, x, n) for(auto i = x; i<(ll)(n); i++)
#define INF  LLONG_MAX
#define all(v) ((v).begin()), ((v).end())
#define sz(v) ((int)((v).size()))
#define pi  acos(-1)
#define mod(n,m) ((n % m + m) % m)
#define eps (1e-8)
#define reset(n, m) memset(n, m, sizeof n)
#define endl '\n'
#define output freopen("output.txt", "w", stdout)
#define mp(x, y, z) { x, {y, z } }

int n, m;
int visited[1001][1001];

bool valid(int i, int j)
{
	return (i >= 0 && j >= 0 && i < n && j < m);
}

vii vec;

int sq(int a)
{
	return a * a;
}

vii ans;

void get()
{
	if (sz(vec) > sz(ans))
		ans = vec;
	erep(i, 1, n)
	{
		erep(j, 1, m)
		{
			if (visited[i][j])
				continue;
			bool flag = true;
			for (auto k : vec)
			{
				int x = k.first, y = k.second;

				if (sq(x - i) + sq(y - j) == 5)
				{
					flag = false;
					break;
				}
			}
			if (flag)
			{
				visited[i][j] = true;
				vec.push_back(
				{ i, j });
				get();
				visited[i][j] = false;
				vec.pop_back();
			}
		}
	}
}

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

	cin >> n >> m;

	if (m > n)
		swap(m, n);

	if (m == 1)
		cout << n;
	else if (m == 2)
		cout << 2 * (2 * (n / 4) + min(n % 4, 2));
	else
		cout << m * n - (m * n) / 2 << endl;

	return 0;
}

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

int main()
{

    int m,n,a,b,c,d,r,n1,m1,a1,b1,ans;
    scanf("%d%d",&n,&m);

    m1=n/2;
    n1=m1;
    if(n&1)n1++;

    b1=m/2;
    a1=b1;
    if(m&1)a1++;

    ans=n1*a1+m1*b1;

    if(n<m)swap(n,m);
    if(m==1)ans=n;
    if(m==2)
    {
        a=n%4;
        b=n/4;
        ans=b*4;
        if(a==1)ans+=2;
        else if(a==2||a==3) ans+=4;
    }
    printf("%d\n",ans);

}

#include<bits/stdc++.h>
#define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define ld long double
#define hell 1000000007
#define hell1 1000000006
#define pb push_back
#define x first
#define y second
#define MAXL 100005
#define pll pair<ll,ll>
#define pii pair<int,int>
#define L LLONG_MAX
#define all(v) (v).begin(),(v).end()
#define tcFile freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);
using namespace std;
//vector<int>prime(15000005,0);
ll mM(ll a,ll b,ll p=hell){ll res = 0;if(a>=p)a %= p;while(b){if (b & 1ll)res = (res + a);if(res>=p) res%= p;a = (2 * a); if(a>=p)a%=p;b >>= 1ll;}return res;}
ll fpow(ll x,ll y,ll p=hell){if(x>=p)x=x%p;ll res=1;while(y){if(y&1ll)res*=x;if(res<0)res+=p;if(res>=p)res%=p;y=y>>1ll;x*=x;if(x<0)x+=p;if(x>=p)x%=p;}return res;}
ll inv(ll n,ll p=hell){return fpow(n,p-2,p);}
ll modmul(ll x,ll y,ll p = hell){if(x<0)x+=p;if(x>=p)x%=p;if(y<0)y+=p;if(y>=p)y%=p;return (x*y)%p;}
ll modadd(ll x,ll y,ll p = hell){if(x<0)x+=p;if(x>=p)x%=p;if(y<0)y+=p;if(y>=p)y%=p;ll temp=x+y;if(temp>=p)temp%=p;return temp;}
/*void sieve(){
    prime[0] = -1;
    prime[1] = 0;
    for(int i=2;i<=15000000;i++)
        if(!prime[i])
            for(int j=i;j<=15000000;j+=i)
            	if(!prime[j])
            		prime[j] = i;
}*/
int main(){
	ios
	int t = 1,tc = 0;
	//cin >> t;
	while(t--){
		int n, m;
		cin >> n >> m;
		if (n == 1 || m == 1) {
			cout << max(n,m) << "\n";
		} else if (n == 2 || m == 2) {
			int other = max(n, m);
			int ans = 0;
			for (int i = 0; i < 2; i++) {
				int len = (other-i+1)/2;
				ans += 2*((len+1)/2);
			}
			cout << ans << "\n";
		} else {
			int ans = n*m + 1;
			ans /= 2;
			cout << ans << "\n";
		}
	}
}

#include <bits/stdc++.h>
using namespace std;
const int inf = 1000111;

struct FastMatching {
    int n;
    vector<int> matchL, matchR, dist;
    vector<bool> seen;
    vector< vector<int> > ke;

    FastMatching(int n) : n(n), matchL(n+1), matchR(n+1), dist(n+1), seen(n+1, false), ke(n+1) {}

    void addEdge(int u, int v) {
        ke[u].push_back(v);
    }

    bool bfs() {
        queue<int> qu;
        for(int u = 1; u <= n; ++u)
            if (!matchL[u]) {
                dist[u] = 0;
                qu.push(u);
            } else dist[u] = inf;
        dist[0] = inf;

        while (!qu.empty()) {
            int u = qu.front(); qu.pop();
            for(__typeof(ke[u].begin()) v = ke[u].begin(); v != ke[u].end(); ++v) {
                if (dist[matchR[*v]] == inf) {
                    dist[matchR[*v]] = dist[u] + 1;
                    qu.push(matchR[*v]);
                }
            }
        }
        return dist[0] != inf;
    }

    bool dfs(int u) {
        if (u) {
            for(__typeof(ke[u].begin()) v = ke[u].begin(); v != ke[u].end(); ++v)
                if (dist[matchR[*v]] == dist[u] + 1 && dfs(matchR[*v])) {
                    matchL[u] = *v;
                    matchR[*v] = u;
                    return true;
                }
            dist[u] = inf;
            return false;
        }
        return true;
    }

    int match() {
        int res = 0;
        while (bfs()) {
            for(int u = 1; u <= n; ++u)
                if (!matchL[u])
                    if (dfs(u)) ++res;
        }
        return res;
    }
};

// Index from 0
// Assume 2 sides have same number of vertices
struct Matching {
    int n;
    vector< vector<int> > ke;
    vector< bool > seen;
    vector< int > matchL, matchR;

    Matching(int n) : n(n), ke(n), seen(n, false), matchL(n, -1), matchR(n, -1) {
    }

    void addEdge(int u, int v) {
        ke[u].push_back(v);
    }

    bool bpm(int u) {
        for(__typeof(ke[u].begin()) v = ke[u].begin(); v != ke[u].end(); ++v) {
            if (seen[*v]) continue;
            seen[*v] = true;

            if (matchR[*v] < 0 || bpm(matchR[*v])) {
                matchL[u] = *v;
                matchR[*v] = u;
                return true;
            }
        }
        return false;
    }

    int match() {
        int res = 0;
        for(int i = 0; i < n; ++i) {
            for(int i = 0; i < n; ++i) seen[i] = false;
            if (bpm(i)) ++res;
        }
        return res;
    }
};

int dx[] = {-2,-2,-1,-1, 1, 1, 2, 2};
int dy[] = {-1,+1,-2,+2,-2,+2,-1,+1};

int n, m;
int vertex(int i, int j) {
    return i * m + j + 1;
}

int main() {
    cin >> n >> m;

    FastMatching M(n * m + 1);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            for (int k = 0; k < 8; ++k) {
                int x = i + dx[k], y = j + dy[k];
                if(x >= 0 && x < n && y >=0 && y < m) {
                    M.addEdge(vertex(i, j), vertex(x, y));
                }
            }
        }
    }
    cout << ((n * m) - ((M.match()) / 2)) << endl;
    return 0;
}

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

int Value[1005][1005];
int N,M;
const int dx[] = {2, 2, 1, 1, -2, -2, -1, -1};
const int dy[] = {1, -1, 2, -2, 1, -1, 2, -2};

#define MAXN 1000005 /// Maximum possible Number of nodes
#define MAXE 8000001 /// Maximum possible Number of edges
#define INF (1<<29)

int ptr[MAXN],Next[MAXE],zu[MAXE];
int n,m,match[MAXN],D[MAXN],q[MAXN];

void init(int _n){ /// initialization _n=number of nodes
  n=_n;
  m=0;
  memset(ptr,~0,sizeof(int)*(n+1));
}
void add_edge(int u,int v){ /// Adding edge between u and v
  Next[m]=ptr[u];ptr[u]=m;zu[m]=v;++m;
}
bool bfs(){
  int u,v;
  register int i;
  int qh=0, qt=0;
  for(i=1; i<=n; i++){
    if(!match[i]){
      D[i]=0;
      q[qt++]=i;
    }
    else D[i]=INF;
  }
  D[0]=INF;
  while(qh<qt){
    u=q[qh++];
    if(u!=0){
      for(i=ptr[u]; ~i; i=Next[i]){
        v=zu[i];
        if(D[match[v]]==INF){
          D[match[v]]=D[u]+1;
          q[qt++]=match[v];
        }
      }
    }
  }
  return D[0]!=INF;
}
bool dfs(int u){
  int v;
  register int i;
  if(u){
    for(i=ptr[u]; ~i; i=Next[i]){
      v=zu[i];
      if(D[match[v]]==D[u]+1){
        if(dfs(match[v])){
          match[v]=u;
          match[u]=v;
          return true;
        }
      }
    }
    D[u]=INF;
    return false;
  }
  return true;
}
int run(){
  int matching=0;
  register int i;
  while(bfs())
    for(i=1; i<=n; i++)
      if(!match[i] && dfs(i))
        matching++;
  return matching;
}
bool isGood(int x,int y){
  return (x<N && y<M && x>=0 && y>=0);
}
int main(){
  cin >> N >> M;
  init(N*M+1);
  for(int i=0;i<N;i++){
    for(int j=0;j<M;j++){
      Value[i][j] = i*M + j + 1;
    }
  }
  for(int i=0;i<N;i++){
    for(int j=0;j<M;j++){
      for(int k=0;k<8;k++){
        int nextX = i + dx[k];
        int nextY = j + dy[k];
        if(isGood(nextX,nextY)){
          add_edge(Value[i][j],Value[nextX][nextY]);
        }
      }
    }
  }
  int Ans = N*M;
  Ans -= (run());
  cout << Ans << endl;
  return 0;
}

#include<bits/stdc++.h>
#include<time.h>
#include<stdlib.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse4")
#define pb push_back
#define mp make_pair
#define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define ll long long
#define pll pair<ll,ll>
#define vll vector<ll,ll>
#define all(a) (a).begin(),(a).end()
#define ff first
#define ss second
#define sz(x) (ll)x.size()
#define hell 1000000007
#define repf(i,a,b) for(ll i=a;i<b;i++)
#define repb(i,a,b) for(ll i=a;i>b;i--)
#define lbnd lower_bound
#define ubnd upper_bound
#define bs binary_search
#define gcd(a,b) __gcd((a),(b))
#define EPS 1e-12
#define lcm(a,b) ((a)*(b))/__gcd((a),(b))
#define sqrt sqrtl
#define cbrt cbrtl
using namespace std;

int32_t main()
{
	IOS
	ll n,m;
	cin>>n>>m;
	ll sum=0,i,j;
	if(n==1)
	{
		cout<<m;
		return 0;
	}
	if(m==1)
	{
		cout<<n;
		return 0;
	}
	if(n==2)
	{
		if(m%2==0)
		{
			ll x=m/2;
			cout<<((x/2)+(x%2))*4;
			return 0;
		}
		else
		{
			ll x=m/2;
			if(x%2)
			cout<<((x/2)+(x%2))*4;
			else
			cout<<((x/2)+(x%2))*4+2;
			return 0;
		}
	}
	if(m==2)
	{
		if(n%2==0)
		{
			ll x=n/2;
			cout<<((x/2)+(x%2))*4;
			return 0;
		}
		else
		{
			ll x=n/2;
			if(x%2)
			cout<<((x/2)+(x%2))*4;
			else
			cout<<((x/2)+(x%2))*4+2;
			return 0;
		}
	}

	for(i=1;i<=n;i++)
	{
		if(i%2)
		{
			ll x=m/2+(m%2);
			sum+=x;
		}
		else
		{
			sum+=(m/2);
		}
		//cout<<sum<<" ";
	}
	cout<<sum;
	return 0;
}

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int main()
{
    int n,m,a,b,ta,tb;
    cin>>n>>m;
    if(n==1)
    {
        cout<<m<<endl;
        return 0;
    }
    if(m==1)
    {
        cout<<n<<endl;
        return 0;
    }
    if(n==2)
    {
        ta=m/4;
        tb=m%4;
        if(tb==1) cout<<ta*4+2<<endl;
        else if(tb>1) cout<<ta*4+4<<endl;
        else cout<<ta*4<<endl;
        return 0;
    }
    if(m==2)
    {
        ta=n/4;
        tb=n%4;
        if(tb==1) cout<<ta*4+2<<endl;
        else if(tb>1) cout<<ta*4+4<<endl;
        else cout<<ta*4<<endl;
        return 0;
    }
    int t=n*m;
    if(t&1)
        cout<<(t+1)/2<<endl;
    else
        cout<<t/2<<endl;
    return 0;
}

#include<iostream>
using namespace std;
int main()
{
	int n,m;cin>>n>>m;if(n>m)swap(n,m);
	if(n==1)cout<<m;
	else if(n==2)cout<<(m/4+(m%4>1))*4+2*(m%4==1);
	else cout<<m*n-(m*n)/2;
}

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

#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);

#define ff first
#define ss second
#define pb push_back
#define pf push_front
#define mp make_pair
#define pu push
#define pp pop_back
#define in insert
#define ld long double
#define debug cout << "Hold right there sparky.....\n";
#define forn(low,high,i) for(i=low;i<high;i++)
#define forrev(high,low,i) for(i = high; i>= low;i--)

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...) 1
#endif
template<class T> ostream& operator<<(ostream &os, vector<T> V) {os << "[ "; for(auto v : V) os << v << " "; return os << "]";}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {return os << "(" << P.first << "," << P.second << ")";}

typedef long long int ll;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef vector<pii> vpii;
typedef vector<pll> vpll;
const ll mod =1e9+7;
const ll maxn =5*100001;
ll power(ll x, ll n) {
  ll res = 1;
  for (; n > 0; n >>= 1) {
    if (n & 1) res = (res * x) % mod;
    x = (x * x) % mod;
  }
  return res;
}

int32_t main()
{

   #ifndef ONLINE_JUDGE
      // for getting input from input.txt
      freopen("input.txt", "r", stdin);
      // for writing output to output.txt
      freopen("output.txt", "w", stdout);
      #endif

    IOS
	ll n,m;
	cin>>n>>m;
	if(n>m)
		swap(n,m);
	if(n==1)
	{
		cout<<m<<endl;
	}
	else
	{
		if(n==2)
		{
			cout<<2*(m/4*2+((m%4)>0)+((m%4)>1));
		}
		else if(m==2)
		{
			cout<<2*(n/4*2+((n%4)>0)+((n%4)>1));
		}
		else
		{
			cout<<(m*n)-(m*n)/2;
		}

	}

}

#define _CRT_SECURE_NO_DEPRECATE
#define _USE_MATH_DEFINES
#include <cstdio>
#include <iostream>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <sstream>
#include <numeric>

#pragma comment(linker, "/STACK:64000000")

#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define EPS 1e-9
#define INF INT_MAX
#define sqr(X) (X) * (X)
#define round(x) (int)((x) + 0.5 + EPS)

using namespace std;

typedef unsigned int uint;
typedef unsigned long long ull;
typedef long long int64;

typedef pair <int, int> pii;
typedef vector <int> vi;
typedef vector <vi> vvi;
typedef vector <uint> vu;
typedef vector <ull> vull;
typedef vector <pii> vpii;
typedef vector <vpii> vvpii;
typedef vector <string> vs;

#define TASK "test"

const int N = 1000 + 42;

bool used[N][N] = {0};
int dx[] = {-2, -2, -1, -1, 1, 1, 2, 2};
int dy[] = {1, -1, 2, -2, 2, -2, 1, -1};

int main()
{
#ifndef ONLINE_JUDGE
//  freopen(TASK ".in", "r", stdin);
//  freopen(TASK ".out", "w", stdout);
#endif

    int n, m;
    cin >> n >> m;

    int ans = 0;

    if (min(n, m) == 2)
    {
        for (int i = 0; i < max(n, m); i++)
            if (i % 4 == 0 || i % 4 == 1) ans += 2;
        cout << ans;
        return 0;
    }

    for (int i = 0; i < n; i++)
        for (int j = (i & 1); j < m; j += 2)
            used[i][j] = true, ans++;

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (!used[i][j])
            {
                bool Ok = true;
                for (int k = 0; k < 8 && Ok; k++)
                {
                    int ii = i + dx[k];
                    int jj = j + dy[k];
                    if (ii < 0 || ii > n - 1) continue;
                    if (jj < 0 || jj > m - 1) continue;
                    if (used[ii][jj]) Ok = false;
                }
                if (Ok) used[i][j] = true, ans++;
            }

    cout << ans;

    return 0;
}

/*input
2 4
3 4
*/

//fold
/*
When you walk through a storm
Hold your head up high
And don't be afraid of the dark
At the end of the storm
There's a golden sky
And the sweet silver song
of the lark
Walk on, through the wind
Walk on, through the rain
Though your dreams be tossed
and blown
Walk on, walk on
With hope in your heart
And you'll never walk alone
YNWA
*/

//hell_hacker
//IT TAKES EVERYTHING and IT IS NOT LUCK
//PICK ME LAST -- COME OUT OF N^WHERE
//WHY NOT?

/*
And you came my way on a winner's day
Shouted loudly come out and play
Can't you tell I got news for you
Sun is shining and so are you
*/
//endfold

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <bits/stdc++.h>

using namespace __gnu_pbds;
using namespace std;

#define endl '\n'
#define fo(i,n) for(i=0;i<n;++i)
#define forr(i,n) for(i=n-1;i>=0;--i)

#define ffs(a) __builtin_ffs(a) // find first set
#define clz(a) __builtin_clz(a) // count leading zeroes
#define ctz(a) __builtin_ctz(a) // count trailing zeroes
#define popc(a) __builtin_popcount(a) // count set bits
#define popcll(a) __builtin_popcountll(a) //count set bits for long long int

#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define yolo "debug_statement"

typedef long long int ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;

const ll inf = 1e9;
const ld eps = 1e-9;
const ld pi=acos(-1);
const ll mod=1000000007;

ll powmod(ll a,ll b,ll mo=mod){ll res=1;a%=mo; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mo;a=a*a%mo;}return res;}

inline ll inv_(ll a) {return powmod(a, mod-2, mod);}
inline ll add(ll a, ll b){a+=b;if(a>=mod)a-=mod;return a;}
inline ll mul(ll a, ll b){return a*1ll*b%mod;}
inline ll sub(ll a, ll b){a-=b;if(a<0)a+=mod;return a;}

typedef tree<
int,
null_type,
less<int>,
rb_tree_tag,
tree_order_statistics_node_update>
ordered_set;

/*USAGE
ordered_set X;
X.insert(1);
X.insert(3);
cout << *X.find_by_order(1) << endl; //3
cout << X.order_of_key(-5) << endl; //0
cout << X.order_of_key(1) << endl; //0
cout << (end(X) == X.order_of_key(100)) << endl; //true since utne elements nahi hai
*/

//fold
#if DEBUG && !ONLINE_JUDGE

    #define debug(args...)     (Debugger()) , args

    class Debugger
    {
        public:
        Debugger(const std::string& _separator = ", ") :
        first(true), separator(_separator){}

        template<typename ObjectType>
        Debugger& operator , (const ObjectType& v)
        {
            if(!first)
                std::cerr << separator;
            std::cerr << v;
            first = false;
            return *this;
        }
        ~Debugger() {  std::cerr << endl;}

        private:
        bool first;
        std::string separator;
    };

    template <typename T1, typename T2>
    inline std::ostream& operator << (std::ostream& os, const std::pair<T1, T2>& p)
    {
        return os << "(" << p.first << ", " << p.second << ")";
    }

    template <typename T1, unsigned long int N>
    inline std::ostream& operator << (std::ostream& os, const std::array<T1, N>& a){
        bool first = true;
        os << "[";
        for(unsigned int i = 0; i < N; i++)
        {
            if(!first)
                os << ", ";
            os << a[i];
            first = false;
        }
        return os << "]";
    }

    template<typename T>
    inline std::ostream &operator << (std::ostream & os,const std::vector<T>& v)
    {
        bool first = true;
        os << "[";
        for(unsigned int i = 0; i < v.size(); i++)
        {
            if(!first)
                os << ", ";
            os << v[i];
            first = false;
        }
        return os << "]";
    }

    template<typename T>
    inline std::ostream &operator << (std::ostream & os,const std::set<T>& v)
    {
        bool first = true;
        os << "[";
        for (typename std::set<T>::const_iterator iii = v.begin(); iii != v.end(); ++iii)
        {
            if(!first)
                os << ", ";
            os << *iii;
            first = false;
        }
        return os << "]";
    }

    template<typename T1, typename T2>
    inline std::ostream &operator << (std::ostream & os,const std::map<T1, T2>& v)
    {
        bool first = true;
        os << "[";
        for (typename std::map<T1, T2>::const_iterator iii = v.begin(); iii != v.end(); ++iii)
        {
            if(!first)
                os << ", ";
            os << *iii ;
            first = false;
        }
        return os << "]";
    }

#else
    #define debug(args...)                  // Just strip off all debug tokens
#endif
//endfold

int idx = 0;
vector<int>adj[2000005];
int gray = 0;
int black = 0;
bool used[2000005];
int n, m;

int getidx(int x, int y){
	return x*1000 + y;
}

void dfs(int x, int color){
	used[x] = true;
	if(color == 0)gray++;
	else black++;
	for(auto it: adj[x]){
		if(!used[it]){
			dfs(it, color ^ 1);
		}
	}
}

bool valid(int x, int y){
    return (x > 0 && x <= n && y > 0 && y <= m);
}

int main(){
    #if ONLINE_JUDGE
        ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
    #endif

    int i, j;
    cin >> n >> m;

    int ans = 0;

    for(i = 1; i <= n; ++i){
        for(j = 1; j <= m; ++j){
            int id = getidx(i, j);
            if(valid(i - 1, j - 2))adj[id].pb(getidx(i-1,j-2));
            if(valid(i - 1, j + 2))adj[id].pb(getidx(i-1,j+2));
            if(valid(i + 1, j - 2))adj[id].pb(getidx(i+1,j-2));
            if(valid(i + 1, j + 2))adj[id].pb(getidx(i+1,j+2));
            if(valid(i - 2, j - 1))adj[id].pb(getidx(i-2,j-1));
            if(valid(i - 2, j + 1))adj[id].pb(getidx(i-2,j+1));
            if(valid(i + 2, j - 1))adj[id].pb(getidx(i+2,j-1));
            if(valid(i + 2, j + 1))adj[id].pb(getidx(i+2,j+1));
        }
    }

    for(i = 1; i <= n; ++i){
        for(j = 1; j <= m; ++j){
            int id = getidx(i, j);
            if(!used[id]){
                gray = 0;
                black = 0;
                dfs(id, 0);
                ans += max(gray, black);
            }
        }
    }

    cout << ans << endl;

    //#if !ONLINE_JUDGE
    //    cout << fixed << setprecision(12) << "-------------------------------------------------\n";
    //    cout << double(clock())/CLOCKS_PER_SEC << " seconds" << endl;
    //#endif
    return 0;
}

#include <iostream>
using namespace std;

int n, m;

int main() {

#ifndef ONLINE_JUDGE
    freopen("input.txt", "rt", stdin);
    freopen("output.txt", "wt", stdout);
#endif

	cin >> n >> m;
	if (n > m) swap(n, m);
	if (n == 1) {
		cout << m;
		return 0;
	}
	if (n == 2) {
		cout << 4 * (m / 4) + 2 * min(2, m % 4);
		return 0;
	}
	cout << (n / 2) * (m / 2) + (((n + 1) / 2) * (((m + 1) / 2)));

    return 0;
}

#pragma optimise GCC(-O3)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define f(a,b,c) for(int a=b;a<c;a++)
#define read(t) ll t; cin>>t;
#define readarr(arr,n) ll arr[n]; f(i,0,n) cin>>arr[i];
#define forstl(i,v) for(auto &i: v)
#define ln endl
#define dbg(x) cout<<#x<<" = "<<x<<ln;
#define dbg2(x,y) cout<<#x<<" = "<<x<<" & "<<#y<<" = "<<y<<ln;
#define dbgstl(v) cout<<#v<<" = \n"; { int c=0; forstl(it,v) \
cout<<"    Term "<< ++c <<" = "<<it<<ln;} cout<<ln;
#define dbgstlp(v) cout<<#v<<" = \n"; { int c=0; forstl(it,v) \
cout<<"    Term "<< ++c <<" = "<<it.fi<<" , "<<it.se<<ln;} cout<<ln;
#define dbgarr(v,s,e) cout<<#v<<" = "; f(i,s,e) cout<<v[i]<<", "; cout<<ln;
#define addEdge(tr,k) f(i,0,k) { ll x,y; cin>>x>>y, tr[x].push_back(y), tr[y].push_back(x);}

mt19937_64 rang(chrono::high_resolution_clock::now().time_since_epoch().count());
int rng(int lim) { uniform_int_distribution<int> uid(0, lim - 1); return uid(rang); }

//														GLOBAL VARS
ll INF =LLONG_MAX;
const ll M= 1000000007;

//														USEFUL FUNCTIONS
ll powm(ll , ll ) ;

// 														MAIN
int main()
{
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);
	cout.tie(NULL);
    //It gets easier day by day, but the hard part is to........
	read(n) read(m)
	if(n>m) swap(n,m);
	if(n==1) cout<<m;
	else if(n>2)
	{
		cout<<((m*n)+1)/2;
	}
	else
	{
		ll mo=m%4;
		ll eta=m/4;
		ll ans=4*eta;
		if(mo==0) cout<<ans;
		else if(mo==1) cout<<ans+2;
		else  cout<<ans+4;
	}

}

//													FUNCTIONS DECLARATIONS
ll powm(ll a, ll b) {
	ll res=1;
	while(b) {
		if(b&1)
			res=(res*a)%M;
		a=(a*a)%M;
		b>>=1;
	}
	return res;
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
using namespace std;
#define fi "input.txt"
#define fa "output.txt"
#define foru(i,l,r) for(int i=l;i<r;i++)
#define ford(i,l,r) for(int i=l;i>r;i--)
#define re return
#define ll long long

const int maxN=1005;
const int maxM=15;
int n,m,k,d,l;
int hd[1000010];

void nhap() {
    cin>>n>>d>>m>>l;
}

void xuly() {
    memset(hd,0,sizeof(hd));
    int u=d;
    hd[0]=1;
    int ans=1;
    while (hd[u]==0) {
        hd[u]=++ans;
        u=(u+d)%m;
    }
    ans=-1;
    ll kq;
    foru(i,l+1,m)
        if (hd[i]>0)
            if (ans==-1 || hd[ans]>hd[i]) ans=i;
    if (ans==-1) {
        kq=1ll*(n-1)*m+l+1;
        while (kq%d!=0) ++kq;
        printf("%I64d",kq);
    } else {
        ll tk=0;
        ans=hd[ans];
        foru(i,1,ans)
            tk+=d;
        cout<<tk;
    }
}

int main() {
    //freopen(fi,"r",stdin);
    //freopen(fa,"w",stdout);
     int n,m;
    cin>>n>>m;
    if (n==1 || m==1) cout<<max(n,m); else
    if (n==2 || m==2) {
        int ans=max(n,m);
        if (ans%2==0) {
            if ((ans/2)%2==0) cout<<ans; else cout<<ans+2;
            re 0;
        }
        cout<<ans+max(((ans-1)/2+1)%2,((ans-2)/2+1)%2);
    } else cout<<n*m-(n*m)/2;
    //fclose(stdin);
    //fclose(stdout);
    re 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>

using namespace std;

int n,m;
int main()
{
  //  freopen("input.txt","r",stdin);
    cin>>n>>m;
    int ans=0;
    if(n>m)
        swap(n,m);
    if(n==1)
    {
        printf("%d\n",m);
    }
    else if(n==2)
    {
        ans=(m/4)*4;
        if(m%4)
        {
            if(m%4>=2)
                ans+=4;
            else
                ans+=2;
        }
        cout<<ans<<endl;
    }
    else
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(i%2)
                {
                    if(j%2)
                        ans++;
                }
                else
                    if(j%2==0)
                        ans++;
            }
        cout<<ans<<endl;
    }
}

#include<bits/stdc++.h>
#define maxn (1000+50)
using namespace std;

int main()
{
		long long n,m;
		cin >> n >> m;
		if (n>m) swap(n,m);
		if (n==1) cout << n*m << endl;
		else if (n==2)
		{
			if (m%4==0) cout << m << endl;
			if (m%4==1) cout << m+1 << endl;
			if (m%4==2) cout << m+2 << endl;
			if (m%4==3) cout << m+1 << endl;
		}
		else
			cout << (n*m+1)/2 << endl;

	return 0;
}

//Hey u r far away to know this
#include <bits/stdc++.h>
using namespace std;
#define     ff      	    	first
#define     pb 	         	push_back
#define     ss          		second
#define     ll      	    	long long
#define     MAX  	       	5000
#define     mpi         		map<int, int>
#define     mpll        		map<ll, ll>
#define     pll         		pair<ll, ll>
#define     plld        		pair<ll, double>
#define     SKILLER     		ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define     vi          		std::vector<int>
#define     vll         		std::vector<ll>
#define     vs          		std::vector<string>
#define     vvi         		std::vector<std::vector<int>>
#define     vvll        		std::vector<std::vector<ll>>
#define     all(v)      		v.begin(), v.end()
#define     allr(v)      		v.rbegin(), v.rend()
#define     loop(i, a, b) 	for(int i = a; i < b; i++)
#define 	  debug(x) 		cout << x <<" " <<"\n";
#define 	  debug1(x, y) 	cout << x << " " << y  << "\n";
#define 	  debug2(x, y, z) 	cout << x << " " << y << " " << z<<"\n";
#define 	  int 			ll
const   int N = 1e6+5, Mod = 1e9 + 7;
int32_t main(){
    	SKILLER;
    	#ifndef ONLINE_JUDGE
        freopen("inputf.in", "r", stdin);
    	//    freopen("outputf.in", "w", stdout);
    	#endif
        int n, m; cin >> n >> m;
        int ans = 0;
        if(n == 2 || m == 2){
        	if(m == 2)
        		swap(n, m);
        	cout << 2 * (2 * (m/4) + min(m%4, 2LL));
        	return 0;
        }
        cout << max(n, max(m, n*m - (n*m)/2));
    	return 0;
}

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;

int main() {
    int R, C;
    scanf( "%d %d", &R, &C );
    if( R > C ) swap( R, C );

    if( R == 1 ) printf( "%d\n", C );
    else if( R == 2 ) {
        int ret = 0;
        for( int i=0; i<C; i++ ) {
            if( i%4 < 2 ) ret += 2;
        }
        printf( "%d\n", ret );
    }
    else printf( "%d\n", R*C/2+(R%2==1&&C%2==1) );
}

/*
    author:  Maksim1744
    created: 22.08.2020 13:38:40
*/

#include <bits/stdc++.h>

using namespace std;

#define ll   long long
#define ld   long double

#define mp   make_pair
#define pb   push_back
#define eb   emplace_back

#define sum(a)     ( accumulate ((a).begin(), (a).end(), 0ll))
#define mine(a)    (*min_element((a).begin(), (a).end()))
#define maxe(a)    (*max_element((a).begin(), (a).end()))
#define mini(a)    ( min_element((a).begin(), (a).end()) - (a).begin())
#define maxi(a)    ( max_element((a).begin(), (a).end()) - (a).begin())
#define lowb(a, x) ( lower_bound((a).begin(), (a).end(), (x)) - (a).begin())
#define uppb(a, x) ( upper_bound((a).begin(), (a).end(), (x)) - (a).begin())

template<typename T>             vector<T>& operator--            (vector<T>& v){for (auto& i : v) --i;            return  v;}
template<typename T>             vector<T>& operator++            (vector<T>& v){for (auto& i : v) ++i;            return  v;}
template<typename T>             istream& operator>>(istream& is,  vector<T>& v){for (auto& i : v) is >> i;        return is;}
template<typename T>             ostream& operator<<(ostream& os,  vector<T>& v){for (auto& i : v) os << i << ' '; return os;}
template<typename T, typename U> istream& operator>>(istream& is, pair<T, U>& p){is >> p.first >> p.second;        return is;}
template<typename T, typename U> ostream& operator<<(ostream& os, pair<T, U>& p){os << p.first << ' ' << p.second; return os;}
template<typename T, typename U> pair<T,U> operator-(pair<T,U> a, pair<T,U> b){return mp(a.first-b.first, a.second-b.second);}
template<typename T, typename U> pair<T,U> operator+(pair<T,U> a, pair<T,U> b){return mp(a.first+b.first, a.second+b.second);}
template<typename T, typename U> void umin(T& a, U b){if (a > b) a = b;}
template<typename T, typename U> void umax(T& a, U b){if (a < b) a = b;}

#ifdef HOME
#define TAG_LENGTH       25
#define LR_LEFT          left
#define LR_RIGHT         right
#define LR_VALUE         value
#define LR_SECOND_VALUE  mn
#include "C:/C++ libs/print.cpp"
#else
#define showl            42;
#define shows            42;
#define show(...)        42;
#define showm(...)       42;
#define showt(...)       42;
#define printTree(...)   42;
#define printGraph(...)  42;
#define printLRTree(...) 42;
#define printMatrix(...) 42;
#define printWGraph(...) 42;
#define debug     if (false)
#endif

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

    int n, m;
    cin >> n >> m;
    int ans = 0;
    for (int i = 0; i < 2; ++i) {
        ans = max({ans, (n + 2) / 3 * m, (m + 2) / 3 * n});
        int cntn = n / 4 * 2 + min(n % 4, 2);
        int cntm = m / 4 * 2 + min(m % 4, 2);
        ans = max(ans, cntn * cntm);
        if (n % 2 == 0 || m % 2 == 0) ans = max(ans, n * m / 2);
        else {
            int cnt = n * (m - 1) / 2;
            cnt += (n + 1) / 2;
            ans = max(ans, cnt);
        }
        swap(n, m);
    }
    cout << ans << endl;

    return 0;
}

//Author: Vineet Shah
//IIT Indore
#include<bits/stdc++.h>
#define rep(i,start,lim) for(long long i=start;i<lim;i++)
#define repd(i,start,lim) for(long long i=start;i>=lim;i--)
#define MOD 1000000007
#define INF 1000000000000000000
#define scan(x) scanf("%lld",&x)
#define print(x) printf("%lld ",x)
#define sz(a) lld((a).size())
#define pb push
#define mp make_pair
#define f first
#define s second
#define YES printf("YES\n")
#define NO printf("NO\n")
#define all(c) (c).begin(),(c).end()
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define br printf("\n")
#define bit(x,i) (x&(1<<i))
using namespace std;
typedef long double ldb;
typedef long long lld;
#define N 1000005
lld tmp,dirx[]={-2,-2,-1,-1,+1,+1,+2,+2},n,m,diry[]={-1,+1,-2,+2,-2,+2,-1,+1};
inline lld pos(lld x,lld y) {return (x-1)*m+y;}
inline bool color(lld x,lld y) {return (x+y)&1;}
inline bool valid(lld x,lld y) {return ((x>=1) and (x<=n) and (y>=1) and (y<=m));}
vector<lld> adj[N];
struct Hopcroft_Karp{
	lld result,x[N],y[N],dist[N];
	lld hopcroft()
	{
		memset(x,0,sizeof x),memset(y,0,sizeof y),result=0;
		while(bfs()) rep(u,1,tmp) if((x[u]==0) and dfs(u)) result++;
		return result;
	}
	bool bfs()
	{
		queue<lld> q;
		rep(u,1,tmp)
			if(!x[u]) dist[u]=0,q.pb(u);
			else dist[u]=INF;
		dist[0]=INF;
		while(!q.empty())
		{
			lld u=q.front();
			q.pop();
			if(dist[u]<dist[0]) rep(i,0,sz(adj[u])) if(dist[y[adj[u][i]]]==INF)
				dist[y[adj[u][i]]]=dist[u]+1,q.pb(y[adj[u][i]]);
		}
		return (dist[0]!=INF);
	}
	bool dfs(lld u)
	{
		if(u!=0)
		{
			rep(i,0,sz(adj[u])) if(dist[y[adj[u][i]]]==dist[u]+1) if(dfs(y[adj[u][i]]))
			{
				y[adj[u][i]]=u,x[u]=adj[u][i];
				return true;
			}
			dist[u]=INF;
			return false;
		}
		return true;
	}
} graph;
int main()
{
	scan(n),scan(m),tmp=n*m+1;
	rep(i,1,n+1) rep(j,1,m+1) if(color(i,j)) rep(k,0,8) if(valid(i+dirx[k],j+diry[k]))
		adj[pos(i,j)].push_back(pos(i+dirx[k],j+diry[k]));
	cout<<((n*m)-(graph.hopcroft()));
	return 0;
}

#include <cstdio>
#include <numeric>
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <queue>
#include <sstream>
#include <deque>

using namespace std;

#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i = 0; i < (n); i++)
#define re return
#define fi first
#define se second
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(abs(x))
#define y0 y3487465
#define y1 y8687969
#define fill(x,y) memset(x,y,sizeof(x))

typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef double D;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<vi> vvi;

template<class T> T abs(T x) { re x > 0 ? x : -x; }

int n;
int m;

int main () {
    scanf ("%d%d", &n, &m);
    if (n > m) swap (n, m);
    if (n == 1) printf ("%d\n", m); else
    if (n == 2) printf ("%d\n", max (m + m % 2, ((m + 2) / 4) * 4)); else printf ("%d\n", (n * m + 1) / 2);
    return 0;
}

/*input

*/

// assic value of ('0'-'9') is(48 - 57) and (a-z) is (97-122) and (A-Z) is(65-90) and 32 for space
// #pragma GCC target ("avx2")
// #pragma GCC optimization ("O3")
// #pragma GCC optimization ("unroll-loops")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;

// order_of_key (k) : Number of items strictly smaller than k .
// find_by_order(k) : K-th element in a set (counting from zero).
using namespace __gnu_pbds;
template<class T> using oset=tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define ll          long long int
#define pb          push_back
#define pii         pair<ll ,ll >
#define vpii        vector< pii >
#define vi          vector<ll >
#define vs			vector< string >
#define vvi         vector< vector< ll > >
#define inf			(ll)1e18
#define all(it,a)   for(auto it=(a).begin();it!=(a).end();it++)
#define F           first
#define S           second
#define sz(x)       (ll )x.size()
#define rep(i,a,b)	for(ll  i=a;i<b;i++)
#define repr(i,a,b) for(ll  i=a;i>b;i--)
#define lbnd        lower_bound
#define ubnd        upper_bound
#define mp          make_pair
#define whatis(x)   cout << #x << " is " << x << "\n";
#define graph(n)    adj(n,vector< ll > () )
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

#define debug(x)     cout << #x << " " << x << endl;
#define debug_p(x)   cout << #x << " " << x.F << " " << x.S << endl;
#define debug_v(x)   {cout << #x << " "; for (auto ioi : x) cout << ioi << " "; cout << endl;}
#define debug_vp(x)  {cout << #x << " "; for (auto ioi : x) cout << '[' << ioi.F << " " << ioi.S << ']'; cout << endl;}
#define debug_v_v(x) {cout << #x << "/*\n"; for (auto ioi : x) { for (auto ioi2 : ioi) cout << ioi2 << " "; cout << '\n';} cout << "*/" << #x << endl;}
const ll N = 1005;
ll dx[]   = {2,-2};
ll dy[]   = {1,-1};
ll n,m;
vvi col(N,vi (N,-1));
ll check(ll x,ll y)
{
	if(x>=0 && y>=0 && x<n && y<m && col[x][y]==-1) return 1;
	return 0;
}

void bfs(ll u,ll v,ll c,ll &cnt0,ll &cnt1)
{

	queue< pair<pii,ll> > q;
	q.push(mp(mp(u,v),c));

	while(!q.empty())
	{
		pair<pii,ll> p = q.front();
		q.pop();

		if(col[p.F.F][p.F.S]!=-1) continue;
		col[p.F.F][p.F.S]=p.S;
		u = p.F.F;
		v = p.F.S;
		c = p.S;

		// cout<<u<<" "<<v<<" "<<c<<"\n";

		if(c==0) cnt0++;
		else cnt1++;

		rep(i,0,2) rep(j,0,2)
		{
			ll x = u+dx[i];
			ll y = v+dy[j];
			if(check(x,y)) q.push(mp(mp(x,y),c^1));
		}

		rep(i,0,2) rep(j,0,2)
		{
			ll x = u+dy[j];
			ll y = v+dx[i];
			if(check(x,y)) q.push(mp(mp(x,y),c^1));
		}

	}

	return ;
}

int solve()
{
	cin>>n>>m;
	ll ans=0;
	rep(i,0,n) rep(j,0,m) if(col[i][j]==-1) {
		ll cnt0=0,cnt1=0;
		bfs(i,j,0,cnt0,cnt1);
		ans+=max(cnt0,cnt1);
	}

	cout<<ans<<"\n";

	return 0;
}

int main()
{
	auto start = chrono::high_resolution_clock::now();

    // freopen("input.txt","r",stdin);
    // freopen("output.txt","w",stdout);

	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	ll test_cases=1;
	//cin>>test_cases;
	while(test_cases--)
		solve();

	auto stop = chrono::high_resolution_clock::now();
	auto duration = chrono::duration_cast<chrono::milliseconds>(stop-start);
	//cout<<"\nduration: "<<(double)duration.count()<<" milliseconds";
}

#include <iostream>
#include <cmath>
#include <map>

using namespace std;

int solve(int n, int m) {
    if (n>m) swap(n,m);
    if (n==1) {
        return m;
    }
    if (n==2) {
        if (m<=4) return 4;
        return 4+solve(n, m-4);
    }
    return int((m+1)/2)*int((n+1)/2) + int(m/2)*int(n/2);
}

int main() {
    int n,m; cin >> n >> m;
    cout << solve(n,m) << endl;
}

#include <stdio.h>
#include <stdlib.h>

int max(int i,int j)
{
    if(i>j) return i;
    else return j;
}

int main()
{
    int m,n;
	while(~scanf("%d%d",&n,&m))
    {
        if(n==1||m==1)
        {
            printf("%d\n",max(m,n));
        }
        else
        {
            if(n==2||m==2)
            {
                if(max(n,m)%4==1)
                {
                    printf("%d\n",(max(n,m)/4)*4+2);
                }
                else
                {
                    if (max(n,m)%4==0)
                    {
                        printf("%d\n",(max(n,m)/4)*4);
                    }
                    else
                    {
                        printf("%d\n",(max(n,m)/4)*4+4);
                    }
                }
            }
            else
            {
                if ((n*m)%2==0)
                {
                    printf("%d\n",n*m/2);
                }
                else
                {
                    printf("%d\n",n*m/2+1);
                }
            }
        }
    }
    return 0;
}

#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define enl printf("\n")
#define case(t) printf("Case #%d: ", (t))
#define ni(n) scanf("%d", &(n))
#define nl(n) scanf("%I64d", &(n))
#define nai(a, n) for (int i = 0; i < (n); i++) ni(a[i])
#define nal(a, n) for (int i = 0; i < (n); i++) nl(a[i])
#define pri(n) printf("%d\n", (n))
#define prl(n) printf("%I64d\n", (n))
#define pii pair<int, int>
#define vii vector<pii>
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
typedef long long ll;
const double pi = acos(-1);
const int MOD = 1e9 + 7;
const int INF = 1e9 + 7;
const int MAXN = 1e6 + 5;
const double eps = 1e-9;
using namespace std;

int f(int x)
{
    return (-2 * x * x * x + 9 * x * x - 12 * x) / 3;
}

int main()
{
    int n, m;
    ni(n), ni(m);
    if (n > m)
        swap(n, m);
    if (n == 1)
        return !pri(m);
    if (n == 2)
        return !pri((m / 4) * 4 + min((m % 4), 2) * 2);
    pri(m * n - (m * n) / 2);
    return 0;
}

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main(){
    int n,m;
    while(cin>>n>>m){
        if(n==1){
            cout<<m<<endl;
            continue;
        }
        if(m==1){
            cout<<n<<endl;
            continue;
        }
        if(n==2){
            int ans=m/4;
            ans*=4;
            m%=4;
            if(m>2)
                m=2;
            ans+=m*2;
            cout<<ans<<endl;
            continue;
        }
        if(m==2){
            int ans=n/4;
            ans*=4;
            n%=4;
            if(n>2)
                n=2;
            ans+=n*2;
            cout<<ans<<endl;
            continue;
        }
        int ans=n*m;
        ans+=(n*m%2);
        cout<<ans/2<<endl;

    }

    return 0;
}

#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <math.h>
#include <iostream>
#include <string>

using namespace std;
int
main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    long long n,m;

    cin >> n >> m;

    if (m == 1) swap(n,m);

    if (n == 1) {
        cout << m;
        return 0;
    }

    if (n > 2 && m > 2) {
        cout << n*m/2 + n*m%2;
        return 0;
    }

    if (m == 2) swap(n,m);

    if (n == 2) {
        if (m == 2)
        {
            cout << 4;
            return 0;
        }

        if ((m%4) == 1)
        {
            cout << ((m-1) + 2);

            return 0;
        } else if ((m%4) == 0) {

            cout << (m*n/2);

            return 0;
        } else if ((m%4) == 2) {

            cout << (m-2) + 4;

            return 0;
        } else if ((m%4) == 3) {

            cout << (m-3) + 4;

            return 0;
        }
    }

    return 0;
}

#include<iostream>
#include<cstdio>

using namespace std;

int main()
{
    int m,n,max1;
    scanf("%d%d",&n,&m);
    if (n==1||m==1)
        max1=n*m;
    else
    {
        if (n==2||m==2)
        {
            if (max(n,m)%4==1)
                max1=(max(n,m)/4)*4+2;
            else
            {
                if (max(n,m)%4==0)
                   max1=(max(n,m)/4)*4;
                else
                    max1=(max(n,m)/4)*4+4;
            }
        }
        else
            max1=(m*n+1)/2;
    }
    printf("%d\n",max1);
    return 0;
}

#include<bits/stdc++.h>

using namespace std;

#define PI 3.141592
#define WHITE 'w'
#define BLACK 'b'

int main(){
	int n, m;
	scanf(" %d %d", &n, &m);
	if(m>n){
		n=m+n;
		m=n-m;
		n=n-m;
	};
	//printf("%d %d\n", n, m);
	if(m==1){
		printf("%d\n", n);
		return 0;
	}
	else if(m==2){
		printf("%d\n", 4*(n/4) + 2*min(n%4, 2));
	}
	else {
		printf("%d\n", (n*m +1)/2);
	};
	return 0;
};

#include <iostream>

using namespace std;
void swap(int &a, int &b)
{
	int t = a; a = b; b = t;
}
int main()
{
	int n, m;
	cin >> n >> m;
	if(m > n)
		swap(m, n);
	if(m == 2&&n==2)
	{
		cout << 4;
		return 0;
	}
	if(m==1)
	{
		cout << n;
		return 0;
	}
	if(m == 2&&n==3)
	{
		cout << 4;
		return 0;
	}
	if(m==2)
	{
		switch(n%4)
		{
		case 0:
			cout << n;
			break;
		case 1:
			cout << n+1;
			break;
		case 2:
			cout << n+2;
			break;
		case 3:
			cout<< n+1;
			break;
		}
		return 0;
	}
	if(n%2==0||m%2==0)
	{
		cout << n*m/2;
		return 0;
	}
	cout << n*m/2+1;
}

#include <cstdio>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <stack>

using namespace std;

int main()
{
	#ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
	#endif
	int n, m;
	cin >> n >> m;
	if (m == 1 || n == 1)
	{
		cout << n * m;
		return 0;
	}
	if (m == 2)
	{
		int ans = 2 * (n / 4);
		if (n % 4 == 3)
			ans += 2;
		else
			ans += n % 4;
		cout << 2 * ans;
		return 0;
	}
	if (n == 2)
	{
		int ans = 2 * (m / 4);
		if (m % 4 == 3)
			ans += 2;
		else
			ans += m % 4;
		cout << 2 * ans;
		return 0;
	}
	cout << (n * m + 1) / 2;
	return 0;
}

#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int main(int argc, char *argv[]) {
	int n, m;
	cin >> n >> m;
	if (m>n) swap(n, m);
	if (m==1)
		printf("%d\n", n);
	else if (m==2)
		printf("%d\n", 2*(2*(n/4) + min(n%4, 2)));
	else
		printf("%d\n", n*m - n*m/2);
	return 0;
}

// (.Y.)™

#define _USE_MATH_DEFINES

#include <cmath>
#include <cstdio>
#include <ctime>

#include <algorithm>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#pragma comment(linker, "/STACK:66777216")

#define  ll          long long
#define ull unsigned long long

#define all(x) x.begin(), x.end()

#define mp make_pair
#define pb push_back

#define DEBUG(x) cout << #x << ": " << (x) << endl;

#define ret return

const int di[] = { 1, 2, 1,-2,-1, 2,-1,-2};
const int dj[] = { 2, 1,-2, 1, 2,-1,-2,-1};

//const int di[] = {-2, -2, -1, -1, 1, 1, 2, 2};
//const int dj[] = {-1, 1, -2, 2, -2, 2, -1, 1};

vector <int> G[4001];

int    L[4001];
int    R[8001];
bool was[4001];

bool kuhn(int u) {
    was[u] = true;

    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];

        if ( R[v] == -1 || (!was[R[v]] && kuhn(R[v])) ) {
            L[u] = v;
            R[v] = u;

            ret(true);
        }
    }

    ret(false);
}

int main() {
#ifndef ONLINE_JUDGE
    freopen( "input.txt", "rt", stdin );
    //freopen("output.txt", "wt", stdout);
#endif

    int n, m;
    cin >> n >> m;

    if ( n >= 5 && m >= 5 ) {
        cout << (n*m+1)/2;
        ret(0);
    }

    int cnt = 0;
    int lol = 0;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            if ( (i+j)&2 )
                continue;

            for (int k = 0; k < 8; k++) {
                int i1 = i+di[k];
                int j1 = j+dj[k];

                if ( 1 <= i1 && i1 <= n &&
                     1 <= j1 && j1 <= m ) {

                    int u = cnt;
                    int v = i1*m + j1;

                    G[u].pb(v);
                }
            }

            cnt++;
        }

    memset(L, -1, sizeof(L));
    memset(R, -1, sizeof(R));

    int res =  0;

    for (int u = 0; u < cnt; u++)
        if ( L[u] == -1  ) {
            memset(was, 0, sizeof(was));

            res += ( kuhn(u) ? 1 : 0 );
        }

    cout << max(res+(lol-lol/2), n*m - (res+(lol-lol/2)));

#ifndef ONLINE_JUDGE
    printf("\n>>> Time of execution %.3f seconds <<<\n", (double)clock() / CLOCKS_PER_SEC);
#endif

    ret(0);
}

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

typedef long long ll;
typedef pair <ll, ll> pll;
typedef pair <int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector < vector<int> > vvi;
typedef vector < vector<ll> > vvl;

#define sl(x) scanf("%lld", &x); //s(x) is for long long int.
#define si(x) scanf("%d", &x);

#define debug true
#define ok if(debug)
#define trace(x) ok cerr << #x << ": " << x << endl;
#define trace2(x, y) ok cerr << #x << ": " << x << " | " << #y << ": " << y << endl;
#define trace3(x, y, z)    ok      cerr << #x << ": " << x << " | " << #y << ": " << y << " | " << #z << ": " << z << endl;
#define trace4(a, b, c, d)  ok cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | "  << #d << ": " << d << endl;
#define trace5(a, b, c, d, e) ok cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << endl;
#define trace6(a, b, c, d, e, f) ok cerr << #a << ": " << a << " | " << #b << ": " << b << " | " << #c << ": " << c << " | " << #d << ": " << d << " | " << #e << ": " << e << " | " << #f << ": " << f << endl;
#define rep(i, a, b) \
		for (int i = int(a); i <= int(b); i++)
#define nrep(i,a,b) \
		for (int i = int(a); i >= int(b); i--)
#define trv(it, c) \
		for (auto it = (c).begin(); it != (c).end(); it++)
#define mkp make_pair
#define pb push_back
#define X first
#define Y second

#define MOD 1000000007 //10^9 + 7

int main()
{
	int n, m;
	cin >> n >> m;
	if ( n > m ) swap ( n, m );
	if  ( n == 1 ) cout <<m;
	else if (  n == 2 ) {
		if ( m == 2) cout <<4 <<endl;
		else if ( m == 3 ) cout <<4<<endl;
		else {
			if ( m % 2 ) cout << m + 1 << endl;
			else {
				if ( m % 4 == 0) cout << m;
				else cout << m + 2;
			}
		}
	}
	else {
		cout <<((n*m)+1)/2;
	}
	return 0;
}

#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
#define rep(i, n) for(ll i = 0; i < (n); i++)
#define F first
#define S second
typedef long long ll;
using namespace std;

const ll N = 1e6 + 9;
ll n, m;
#define min(a,b) (a<b?a:b)

int main()
{_
    cin >> n >> m;
    if (m > n) swap(n, m);
    if (m == 1) {
        cout << n * m;
        return 0;
    }
    if (m == 2) {
        cout << (n * m / 8) * 4 + min(4, (n * m) % 8);
        return 0;
    }
    cout << n * m / 2 + ((n * m) % 2 == 1);
}

#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m;
cin>>n>>m;
if (n>m)swap(n,m);
if (n==1||m==1) cout<<n*m;
else if (n==2) cout<<((m%4==1)*(-2)+(m +3)/4*4);
else cout<<(n*m+1)/2;
return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define fr(i,a,b) for (int i = (a), _b = (b); i <= _b; i++)
#define frr(i,a,b) for (int i = (a), _b = (b); i >= _b; i--)
#define rep(i,n) for (long long i = 0, _n = (n); i < _n; i++)
#define repr(i,n) for (long long i = (n) - 1; i >= 0; i--)
/*Author Ritick Goenka || ritick(codechef) ||ritick(codeforces) */
/*IIT Roorkee = <3 */
#define ull unsigned long long
#define ll long long
#define pb push_back
#define mp make_pair
#define ff first
#define ss second

#define debug(x) cout<<#x<<": "<<x<<endl
#define dbug(x,y) cout<<x<<" "<<y<<endl

#define PI 3.1415926535897932385
#define INF 1000000000000000000
#define EPS 1e-7
#define MAXN 100000
#define MOD 1000000007
#define dec decr
//END OF COMPETITVE PROGRAMMING TEMPLATE
ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b % a, a);
}
ll modexp(ll x, ll y, ll p)
{
    ll res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;
        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}
vector<ll>v[202];
ll mark[202];
ll dia(ll n)
{
    mark[n]=1;
    ll x=0;
    rep(i,v[n].size())
    {
        if(mark[v[n][i]]==0)
        {
            x=max(x,dia(v[n][i]));
        }
    }
    return x+1;
}
int main ()
{
	ios_base::sync_with_stdio(false);
            cin.tie(NULL);
	    #ifndef ONLINE_JUDGE
  	    freopen("input.txt", "r", stdin);
   	    freopen("output.txt", "w", stdout);
   	    #endif
            ll n,m;
            cin>>n>>m;
            if(n==1||m==1||(n==2&&m==2))
            {
                cout<<n*m;
                return 0;
            }
            if((n==2&&m%2==1)||(n%2==1&&m==2))
            {
                cout<<n*m/2+1<<endl;
                return 0;
            }
            else if((n==2&&m%4==2)||(n%4==2&&m==2))
            {
                cout<<n*m/2+2<<endl;
                return 0;
            }
            else
            {
                cout<<(n*m+1)/2;
            }

            return 0;
}

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<climits>
#include<algorithm>
#include<numeric>
#include<functional>
#include<cstdio>
#include<cstdlib>
using namespace std;

#define inpFile(f) freopen(f,"r",stdin)
#define outFile(f) freopen(f,"w",stdout)
#define FOR(i,a,b) for(int i=a; i<=b; ++i)
#define REP(i,n) for(int i=0; i<n; ++i)
#define SI(x) scanf("%d",&x)
#define fill(ar,val) memset(ar,val,sizeof(ar))
#define pb push_back
#define bit(n) (1<<(n))
#define firstSetBit(i) ((i)&(-i))
#define ull unsigned long long
#define ll long long
#define MI INT_MAX

int main()
{
    int n,m;
    cin>>n>>m;
    int sum=0;
    if(n==1) {
        sum += m;
    }

    else if(m==1) {
        sum+=n;
    }
    else if(n==2) {

        int f= m%2;
        int g= m/2;
        if(g%2==1) {
            sum += (g/2+1)*4;
        }
        else {
            sum += (g/2)*4;
            sum += (f*2);
        }
    }
    else if(m==2) {

        int f= n%2;
        int g= n/2;
        if(g%2==1) {
            sum += (g/2+1)*4;
        }
        else {
            sum += (g/2)*4;
            sum += (f*2);
        }
    }
    else {

      if(n%2==1) {
         int a= n/2+1;
        if(m%2==1) {
            sum += a*(m/2+1);
            sum += (a-1)*(m/2);
        }
        else {
            sum += (a*(m/2) + (a-1)*(m/2));
        }
        }
      else {
          int a= n/2;
          if(m%2==1) {
              sum += a*(m/2+1);
              sum += a*(m/2);
          }
          else {
              sum += (2*a*(m/2));
          }
      }
    }
      cout<<sum<<endl;
      return 0;
}

#include<bits/stdc++.h>
using namespace std;
int n,m;
int ans;
int main()
{
	cin>>n>>m;
	if(n>m)swap(n,m);
	if(n==1)
	{
		cout<<m<<endl;
		return 0;
	}
	if(n==2)
	{
		if(m%4<=2)ans=m+m%4;
		else ans=m+1;
	}
	else ans=(n*m+1)/2;
	if(ans<0)ans=-ans,cout<<"-";
	cout<<ans;
	return 0;
}

#include<iostream>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<fstream>
using namespace std;
typedef long long int ll;
int xx[]={1,1,1,0,-1,-1,-1,0};
int yy[]={-1,0,1,1,1,0,-1,-1};
ll gcd(ll a,ll b)
{ return ((a%b==0)?b:gcd(b,a%b)) ;}

int main()
{
    //freopen("input.txt","r",stdin);
    // freopen("output.txt","w",stdout);
     int n,m,k;
     cin>>n>>m;
     if(n>m)
        swap(n,m);
     if(n==1){
        cout<<m<<endl;
        return 0;
     }
     if(n==2)
     {
         k = m%4;
        if(k==3)
            k = 2;
         cout<<(m/4)*4 + k*2<<endl;;
         return 0;
     }

     cout<<(n*m+1)/2<<endl;

 return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define sd(x) scanf("%d", &x)
#define boost ios_base::sync_with_stdio(false);
#define mp make_pair
#define pb push_back
#define all(a) a.begin(), a.end()
#define f first
#define s second

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

const int mod = 1000000007;
const int inf = 50000000;
const int maxn = 1010;

int dx[] = {2, 1, -1, -2, 2, 1, -1, -2};
int dy[] = {1, 2, 2, 1, -1, -2, -2, -1};
int vis[maxn][maxn], arr[2], n, m;

int isvalid(int x, int y)
{
	if(x>=1 && x<=n && y>=1 && y<=m)
		return 1;
	return 0;
}

void dfs(int x, int y, int ind)
{
	int i, nx, ny;
	vis[x][y] = 1;
	arr[ind]++;
	for(i=0; i<8; i++){
		nx = x + dx[i];
		ny = y + dy[i];
		if(isvalid(nx, ny) && !vis[nx][ny])
			dfs(nx, ny, ind^1);
	}
}

int main()
{
	//freopen("i.txt", "r", stdin);
	//freopen("o.txt", "w", stdout);
	int i, j, ans = 0;
	scanf("%d%d", &n, &m);
	for(i=1; i<=n; i++){
		for(j=1; j<=m; j++){
			if(!vis[i][j]){
				arr[0] = arr[1] = 0;
				dfs(i, j, 0);
				ans+=max(arr[0], arr[1]);
			}
		}
	}
	printf("%d\n", ans);

	return 0;
}

#include "bits/stdc++.h"
using namespace std;
#define fast ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ll long long int
#define int ll
// #define double long double
//#define slld(t) scanf("%lld",&t)
//#define sd(t) scanf("%d",&t)
//#define pd(t) printf("%d\n",t)
//#define plld(t) printf("%lld\n",t)
#define vec vector < int >
#define vecp vector < pair < int , int > >
#define ff first
#define ss second
#define pb push_back
#define mp make_pair
#define debug(x)   cerr<<#x<<": "<<x<<endl
#define pii pair < int , int >
#define pll pair < ll , ll >
#define debug(x)   cerr<<#x<<": "<<x<<endl
#define mod  1000000007
#define N   300005
#define mod1 1000000007
#define mod2 998244353
#define bitcnt __builtin_popcountll
#define PI acos(-1)
//#define endl "\n"
#define inf 1e+18
#define MAX 1000
int mul(int x , int y) { return (x*y)%mod;}

signed main(){
  fast;

  int n , m , val3;
  cin >> n >> m;

  int val1 = n*((m+2)/3) + (m>3 && m%3 == 2) + 2*(m>3 && m%3 == 0);
  int val2 = m*((n+2)/3) + (n> 3 && n%3 == 2) + 2*(n > 3 && n%3 == 0);
  if((n*m)%2==0) val3 = n*m/2;
  else val3 = (n*m + 1)/2;
  cout << max(val3 , max(val1 , val2)) << endl;
}

#include<bits/stdc++.h>
using namespace std;
int n,m;
int ans;
int tt;
int main()
{
	cin>>n>>m;
	if(n==1)
	{
		cout<<m;
		return 0;
	}
	if(m==1)
	{
		cout<<n;
		return 0;
	}
	if(n==2)
	{
		cout<<m;
		return 0;
	}
	if(m==2)
	{
		cout<<n;
		return 0;
	}
	if(n==5&&m==3)
	{
		cout<<8;
		return 0;
	}
	if(n==3||m==3)
	{
		cout<<6;
		return 0;
	}
	tt=m/3;
	tt*=n;
	int b=m%3;
	if(m>=1) tt+=n;
	ans=max(ans,tt);
	swap(n,m);
	tt=m/3;
	tt*=n;
	b=m%3;
	if(m>=1) tt+=n;
	ans=max(ans,tt);
	cout<<ans;
	return 0;
}

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using dijkstra = priority_queue<T, vector<T>, greater<T>>;

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define fbo find_by_order  // k th index
#define ook order_of_key   // strictly smaller than k
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define max_ull 18446744073709551615
#define max_ll 9223372036854775807
#define lead_zero(x) __builtin_clzll(x)
#define trail_zero(x) __builtin_ctzll(x)
#define total_1s(x) __builtin_popcountll(x)
#define first_1(x) __builtin_ffsll(x)
#define log2_(x) __builtin_clz(1) - __builtin_clz(x)
#define isLeap(x) ((x % 400 == 0) || (x % 100 ? x % 4 == 0 : false))
#define QUERY           \
    int test;           \
    scanf("%d", &test); \
    for (int _T = 1; _T <= test; _T++)
#define FAST ios_base::sync_with_stdio(0), cin.tie(0)
#define all(v) v.begin(), v.end()
#define reunique(v) v.resize(std::unique(all(v)) - v.begin())
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pul pair<ull, ull>
#define ff first
#define ss second
#define MERGE(v1, v2, v) merge(all(v1), all(v2), back_inserter(v))
#define MP make_pair
#define EB emplace_back
#define read freopen("input.txt", "r", stdin)
#define write freopen("output.txt", "w", stdout)
#define in_range(v, r, l) upper_bound(all(v), r) - lower_bound(all(v), l)
#define LCM(a, b) (a / __gcd(a, b)) * b;

ll rdn(int y, int m, int d) {
    /* Rata Die day one is 0001-01-01 */
    if (m < 3)
        y--, m += 12;
    return 365 * y + y / 4 - y / 100 + y / 400 + (153 * m - 457) / 5 + d - 306;
}
/* Direction arrays */
/*int dx[] = {1,-1,0,0}, dy[] = {0,0,1,-1};                             */  // 4Direction
/*int dx[] = {1,-1,0,0,1,1,-1,-1}, dy[] = {0,0,1,-1,1,-1,1,-1};         */  // 8Direction
int dx[] = {1,-1,1,-1,2,2,-2,-2} , dy[] = {2,2,-2,-2,1,-1,1,-1};       // KnightDirection
/* int dx[] = {2,-2,1,1,-1,-1} , dy[] = {0,0,1,-1,1,-1};                */  // HexagonalDirection
/* int day[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; */
const int N = 1009;
int ara[N][N];
int main() {
    int n,m;
    cin>>n>>m;
    int ans1=0;
    int ans2=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(i%2==j%2)ans1++;
            else ans2++;
        }
    }
    if(ans1>ans2){
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(i%2==j%2){
                    for(int k=0;k<8;k++){
                        int px=dx[k]+i;
                        int py=dy[k]+j;
                        if(px<n && py<m && px>-1 && py>-1)ara[px][py]=1;
                    }
                }
            }
        }
    }
    else{
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (i % 2 != j % 2) {
                    for (int k = 0; k < 8; k++) {
                        int px = dx[k] + i;
                        int py = dy[k] + j;
                        if (px < n && py < m && px > -1 && py > -1)
                            ara[px][py] = 1;
                    }
                }
            }
        }
    }
    int ans=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            if(ara[i][j]==0)ans++;
        }
    }
    cout<<ans<<"\n";
}

#include <bits/stdc++.h>
#define  ll long long
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define For(i,r,l) for(ll i=r-1;i>=l;i--)
#define ITER(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
using namespace std;

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	int n,m;
	cin>>n>>m;
	cout<<max(((n+2)/3)*m,((m+2)/3)*n)<<endl;

	exit(0);
}

#include<bits/stdc++.h>

using namespace std;

#define ll long long
const int N = 201;

int main(void)
{

  int n,m; cin>>n>>m;

  int ans = 0;

  for(int i=1; i+2<=m; i+=2)
  {
    ans += n;
  }
  if(m%2 == 1)
    ans += ceil(double(n)/double(2));
  ans = max(ans,n);
  ans = max(ans,m);
  cout<<ans<<endl;

  return 0;
}

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <string>

using namespace std;

int n, m;

int main()
{
	//~ freopen("a.in", "r", stdin);
	//~ freopen("a.out", "w", stdout);

	cin >> n >> m;

	if (n == 1)
	{
		cout << m;
		return 0;
	}

	if (m == 1)
	{
		cout << n;
		return 0;
	}

	cout << max(max((n - 1) / 3 * m + m, (m - 1) / 3 * n + n), (n * m + 1) / 2);

	return 0;
}

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define IOS {ios :: sync_with_stdio(false); cin.tie(0);cout.tie(0); }
#define F first
#define S second
#define pb push_back
typedef long double ld;
#define deci(n) cout << fixed << setprecision(n);
typedef long long ll;
#define all(a) a.begin(), a.end()
#define pll pair<ll, ll>
#define bits(x) __builtin_popcount(x)
#define fori(n)  for (ll i = 0; i < n; i++)
#define fori2(n) for(ll i=1;i<=n;i++)
#define forj(n)  for (ll j = 0; j < n; j++)
#define forj2(n) for(ll j=1;j<=n;j++)
#define fork(n)  for (ll k = 0; k < n; k++)
#define fork2(n) for(ll k=1;k<=n;k++)
#define vll vector <ll>
#define mll map <ll, ll>
#define vpll vector <pll>
const ll md = 1e9 + 7;

#define BSET(a, p) ((a) | (1ll << (p)))
#define BCHK(a, p) ((a) & (1ll << (p)))
#define BXOR(a, p) ((a) ^ (1ll << (p)));
#define BREM(a, p) (BCHK(a, p)?(BXOR(a, p)):(a))
#define BSHO(a, N) (bitset<N>(a))
// const ll N = 100005;
// ll fac[N] = {1};
// #define calfac for(ll i=1  ;i<N;i++) fac[i] = (fac[i-1]*i)%md;
// ll C[N+1][M+1];
// void  ncr(){
//     ll n = N,k = M;
//     for (ll i = 0; i <= n; i++) {
//         for (ll j = 0; j <= min(i, k); j++) {
//             if (j == 0 || j == i)  C[i][j] = 1;
//             else C[i][j] = C[i - 1][j - 1] +  C[i - 1][j];
//         }
//     }
// }

#define RBTTYPE int
#define ordered_set tree<RBTTYPE, null_type, less<RBTTYPE>, rb_tree_tag,tree_order_statistics_node_update>

ll modexp(ll x, ll ex) {
    ll ans = 1ll;
    while (ex > 0) {
        if (ex & 1ll) ans = (ans * x) % md;
        ex >>= 1ll;
        x = (x * x) % md;
    }
    return ans;
}
ll modInv(ll a)
{
    return pow(a,md-2);
}

// ll nCr(ll n,ll r)
// {
//     return (fac[n]*modInv((fac[r]*fac[n-r])%md))%md;
// }

ll po(ll x,ll n){
    if(n==0) return 1;
    if(n%2==1) return (x*po(x,n-1));
    else {
        ll k=po(x,n/2);
        return (k*k);
    }
}

ll gcd(ll x, ll y) {
    if (x < y) return gcd(y, x);
    if (y == 0) return x;
    return gcd(y, x % y);
}

int32_t main(){
    IOS;
    ll i,j,k,n,m,p,q;
    cin >> n >> m;
    if(n==1 || m==1 || (n==2 && m==2) ) cout << n*m <<"\n";
    else {
        cout << ((m+1)/2) * ((n+1)/2) + (n/2 )* (m/2);
    }

}

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int main()
{
	int n, m;
	cin >> n >> m;
	if(n < m)
		swap(n, m);

	if(m == 1)
	{
		cout << n;
		return 0;
	}
	if(m == 2)
	{
		if(n == 2)
		{
			cout << 4;
		}
		else
		{
			if(n%4 > 1)
				cout << n + 1;
			else
				cout << n;
		}
		return 0;
	}
	cout << (m*n+1)/2;

	return 0;
}

//Powered by [KawigiEdit] 2.0!

#include<bits/stdc++.h>
using namespace std;
#define Sd(a) scanf("%d",&a)
#define Sl(a) scanf("%lld",&a)
#define Pd(a) printf("%d\n",a)
#define Pl(a) printf("%lld\n",a)
#define ll long long

int main()
{
    ll n,m;
    cin>>n>>m;
    if(n>m)
        swap(n,m);

    if(n==1&&m==1)
        cout<<1<<endl;
    else if(n<=2&&m<=2)
        cout<<n*m<<endl;
    else if(n==2&&m==3)
        cout<<4<<endl;
    else
        cout<<(n*m)/2<<endl;
    return 0;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>

using namespace std;

 int n,m,ans;

   int main()
{
   #ifndef ONLINE_JUDGE
      freopen("a.in","r",stdin);
      freopen("a.out","w",stdout);
   #endif
      scanf("%d%d",&n,&m);

      if (n == 1 || m == 1)  printf("%d",max(n,m)); else
        {
          ans = (n * m) / 2;
          if ((n == 2 || m == 2) && (n % 2 == 1 || m % 2 == 1))  ans++;
          printf("%d",ans);
        }

         return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define pi pair<ll,ll>
#define pii pair<ll,pi>
#define mp make_pair
#define mod 1000000007
#define f first
#define s second
#define pb emplace_back
#define fr freopen("input-1.txt","r",stdin)
#define fo freopen("input-25.txt","w",stdout)
int main(){
ll n,m;
cin>>n>>m;
ll ans=0;
ll ans1=0;
for(int i=1;i<=n;i++){
    if(i&1){
        ans+=(m+1)/2;
        ans1+=(m/2);
    }
    else{
        ans1+=(m+1)/2;
        ans+=(m/2);
    }
}
ans=max(ans,ans1);
ans=max(ans,((n+2)/3)*m );
swap(n,m);
ans=max(ans,((n+2)/3)*m);
cout<<ans;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>

using namespace std;

 int n,m,ans,i,j;

   int main()
{
   #ifndef ONLINE_JUDGE
      freopen("a.in","r",stdin);
      freopen("a.out","w",stdout);
   #endif
      scanf("%d%d",&n,&m);

      for(i = 1; i <= n; i++)
       for(j = 1; j <= m; j++)
           if ((i % 2 == 1 && j % 2 == 1) || (i % 2 == 0 && j % 2 == 0)) ans++;

           printf("%d",ans);

         return 0;
}

/*
username: leandro
PROG:
*/
#include <cstdio>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <complex>
#include <set>
#include <map>
#include <sstream>
#include <queue>
#include <stack>

using namespace std;

//////////////////////////////////////
typedef long long i64;
typedef complex<double> pnt;
typedef pair<int, int> pii;
typedef vector<int> vi;
//////////////////////////////////////
const int oo = 1 << 30;
const double PI = M_PI;
const double EPS = 1e-15;
//////////////////////////////////////
#define F first
#define S second
#define foreach(i, u) \
        for (typeof(u.begin()) i = u.begin(); i != u.end(); i++)
#define REP(i, n) \
        for (int i = 0; i < (n); i++)
#define FOR(i, n) \
        for (int i = 1; i <= (n); i++)
//////////////////////////////////////
#define DEBUG(x) \
        cout << #x << " = " << x << endl

int main()
{
    cin.sync_with_stdio(false);

    int R, C, ans = 0;
    cin >> R >> C;

    for (int i = 0; i < R; i++)
        for (int j = 0; j < C; j++)
            if ((i+j)%2) ans++;

    ans = max(ans, R*C-ans);

    if (R == 1 || C == 1)
        ans = R*C;

    if (R == 2 && C == 2)
        ans = 4;

    cout << ans << endl;

    //system( "pause" );

    return 0;
}

#include <cstdio>
#include <vector>
#include <cstring>

using namespace std;

int dx[] = {2,2,-2,-2,1,1,-1,-1};
int dy[] = {1,-1,1,-1,2,-2,2,-2};
int n, m, TT, N;
int visited[1010*1010];
int par[1010*1010];
vector<int> v[1010*1010];

inline int indx(int i, int j) {
    return i*m + j;
}

bool dfs(int u) {
    if (visited[u] == TT) return false;
    visited[u]=TT;
    for (int i=0;i<(int)v[u].size();i++) {
        if (par[v[u][i]]!=-1 and par[v[u][i]]!=u) {
           if (dfs(par[v[u][i]])) {
                par[u] = v[u][i];
                par[v[u][i]] = u;
                return true;
           }
        } else if (par[v[u][i]] == -1) {
            par[u] = v[u][i];
            par[v[u][i]] = u;
            return true;
        }
    }
    return false;
}

int main() {

   memset(visited,0xff,sizeof(visited));
   TT=-1;

    scanf("%d %d",&n,&m);
    if (n == 1) {
        printf("%d\n",m);
        return 0;
    }
    if (m == 1) {
        printf("%d\n",n);
        return 0;
    }
    N = n*m;
    for (int i=0;i<N;i++) {
        v[i].clear();
        par[i] = -1;
    }

    int resp = 0;
    int ares=0;
    for (int i=0;i<n;i++)
        for (int j=0;j<m;j++) {
            bool tempar = false;
            for (int k=0;k<8;k++) {
                int ni = i+dx[k];
                int nj = j+dy[k];
                if (!(0 <= ni and ni < n and 0 <= nj and nj < m)) continue;
                v[indx(i,j)].push_back(indx(ni,nj));
                ares++;
                tempar=true;
            }
            if (!tempar)
                resp++;// sozinho pode
        }

        //1os deles , passo inicial gulosao
        for (int i=0;i<N;i++)
            for (int j=0;j<(int)v[i].size();j++)
                if (par[i] == -1 and par[v[i][j]] == -1) {
                    par[i] = v[i][j];
                    par[v[i][j]] = i;
                    resp++;
                    break;
                }
        //printf("guloso = %d\n",resp);
                //iku de verade!
        for (int i=0;i<N;i++) if (par[i] == -1) {
            TT++;
            if (dfs(i))
                resp++;
        }

        printf("%d\n",N-resp);

    return 0;
}

#include <bits/stdc++.h>
#define ll long long
#define mp make_pair
#define EPS 1e-15
#define MOD 1000000007

/*
*
*Zaiiiin
*
*/

using namespace std;

typedef pair<int,int> ii;
typedef pair<ll,ll> pll;
typedef vector<ii> vii;
typedef vector<pll> vll;
typedef vector<int> vi;
typedef vector<ll> vl;

const long double pi = acos(-1);
const int n_ = 1e5 + 5;

int n, m;

int main()
{
  #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
  #else
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
  #endif

  cin >> n >> m;
  if(n == 1) cout << m;
  else if(m == 1) cout << n;
  else if(n == 2 && m > 4) cout << m + 1;
  else if(m == 2 && n > 4) cout << n + 1;
  else cout << max((n * m + 1) / 2, 4);
  return 0;
}

#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1000005;
const double eps = 1e-8;
typedef __int64 lld;
const lld INF = 1000000000000000000L;

int fac[maxn], cnt;
lld num[10];
char s[maxn], ss[maxn];

void Swap(int &a, int &b) {
    int t=a;
    a=b; b=t;
}
int main() {
    int n, m;
    while(scanf("%d%d", &n, &m)!=EOF) {
        if(m<n) Swap(n, m);
        else if(n<=2 && m<=2) printf("%d\n", n*m);
        else if(n==2) printf("%d\n", m%2 ? m+1: m);
        else if(n==1) printf("%d\n", m);
        else printf("%d\n", (n*m+1)/2);
    }
    return 0;
}

//#include <bits/stdc++.h>
#include <bits/stdc++.h>
#include <string>
#include <stdio.h>
#include <string.h>
#define all(v)          v.begin(),v.end()
#define allr(v)         v.rbegin(),v.rend()
#define rep(i,m)        for(int i=0;i<m;i++)
#define REP(i,k,m)      for(int i=k;i<m;i++)
#define repd(i,m)        for(int i=m;i>=0;i--)
#define P(x)				cout<<#x<<" = { "<<x<<" }\n"
#define mem(a,b)        memset(a,b,sizeof(a))
#define mp              make_pair
#define pb              push_back
#define SORT(ptr , k )  sort ( ptr , ptr + k );
#define OO ((ll)1e12)
#define ooo -100000000
#define small  INT_MIN;
#define big  INT_MAX;
// #undef to remove macro
#include <cmath>
#include <complex>

using namespace std;
typedef long long ll;
typedef double db;
typedef long double   	  ld;
typedef vector<int>       vi;
typedef vector<bool>       vb;
typedef vector<double>    vd;
typedef vector< vi >      vvi;
typedef vector< vd >      vvd;
typedef vector<string>    vs;
typedef bitset<20> MASK;
//typedef  pair < int, string > point ;
#define mo 1000000007
#define INF 10000
#define sz(v)          ((int)((v).size()))
//std::ios_base::sync_with_stdio(false); means  i will not deal with c lang that will speed
const int oo = (int) 1e9;
const double eps = 1e-7;
#define md 1000000007
#define black 0;
#define white 1;
const int MAXN=1e5+10;
int dx[] = {1, 0, 0, -1, -1, -1, 1, 1};
int dy[] = {0, 1, -1, 0, 1, -1, 1, -1};
vi kmp ;

int main() {
//  cin.tie(0);
 // cin.sync_with_stdio(0);
 int n , m ;
 cin >> n >> m ;
 if (min( m , n  ) == 1 ){
    cout << max(m , n ) << endl;
 return 0 ;
 }
 if (min( m , n  ) == 2 ){
        if (max(m , n ) == n && n %2 == 0 && n > 4)
        cout << n + 2 << endl;

 else    if ( max(n,m) &1 )
    cout << max(m , n ) + 1 << endl;
 else cout << max(m , n ) << endl;

 return 0 ;
 }

 if (m&1){
 int u = ceil(m / 2.0 );
 u *= ceil(n/2.0);
 u += ( m / 2 )*(n/2);
 cout << u << endl;

 return 0;
 }
 cout << n*m/2<<endl;

}

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

#pragma comment(linker, "/STACK:16777216")
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair <int , int> pii;
typedef vector <int> vi;
typedef vector <pii> vii;

#define pb push_back
#define mp make_pair
#define all(x) (x).begin() , (x).end()
#define forit(it, v) for (it = (v).begin(); it != (v).end(); ++it)
#define forn(i, n) for (int i = 0; i < ((int)(n)); ++i)
#define forab(i, a, b) for (int i = (int)(a); i < ((int)(b)); ++i)
#define y0 y123456789
#define y1 y234895
#define hash hash123456789
#define rank rank123456789
#define sz(x) ((int) (x).size() )
#define re return
#define sqr(x) ((x) * (x))
#define fin freopen("input.txt","r",stdin)
#define fout freopen("output.txt","w",stdout)
const double pi = 3.141592653589793238462;
const int nmax = 200000;
const int hash_base = 119;
const long long inf = 1e9;

int n , m ;

int fn(int n , int m)
{
    int ans = 0 ;
    for (int i = 1 ; i <= m ; i += 3 )
        ans += n;
    return ans;
};

int f2(int m)
{
    int ans = 0 ;
    for (int i = 1 ; i <= m ; i ++ )
    {
        ans += 2;
        i ++ ;
        if ( i <= m )
            ans += 2;
        i += 2;
    };
    return ans;
};

int f3(int m)
{
    int ans = 0 ;
    for (int i = 1 ; i <= m ; i ++ )
        if ( i % 2 == 1 )
            ans += 2;
        else
            ans ++ ;
    return ans;
};

int main()
{
cin >> n >> m ;
if ( min(n , m) == 1 )
    printf("%d\n",max(n , m) );
else
{
    if ( n == m && n == 2 )
        printf("4\n");
    else
    {
        if ( n == m && n == 3 )
            printf("5\n");
        else
        {
            if ( min(n , m) == 2 )
                printf("%d\n",max(f2(max(n , m) ) , max(n , m) ) );
            else
            if ( min(n , m) == 3)
                printf("%d\n",f3(max(n , m) ));
            else
                printf("%d\n",max(fn(n ,m) , fn(m , n) ) );
        };
    };
};
return 0;
}

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int main()
{
    int n,m,a,b,ta,tb;
    cin>>n>>m;
    if(n%3==0) a=n/3;
    else a=n/3+1;
    ta=m*a;
    if(m%3==0) b=n/3;
    else b=n/3+1;
    tb=n*b;
    ta=ta>tb?ta:tb;
    cout<<ta<<endl;
    return 0;
}

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#  include <intrin.h>
#  define __builtin_popcount __popcnt
#endif

#define _USE_MATH_DEFINES
#include <stdio.h>
#include <algorithm>
#include <functional>
#include <cstring>
#include <map>
#include <queue>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <math.h>
#include <set>
#include <list>
#include <ctime>
#include <bitset>
#include <deque>
#include <random>
#include <iomanip>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <stack>

#define setzero(arr) memset(arr, 0, sizeof(arr))
#define fi(i, from, to) for(int i = (from); i < (to); i++)
#define fri(i, from, to) for(int i = (from); i >= (to); i--)
#define fa(it, col) for(auto (it) = (col).begin(); (it) != (col).end(); (it)++)
#define fra(it, col) for(auto (it) = (col).rbegin(); (it) != (col).rend(); (it)++)
#define getBit(vv, bit) ((vv & (lol)(1LL << (31 - bit))) == 0LL ? 0 : 1)
#define getBit64(vv, bit) ((vv & (lol)(1LL << (63 - bit))) == 0LL ? 0 : 1)
#define MOD 1000000007
#define PI 3.14159265358979323846

using namespace std;
typedef unsigned long long lol;
typedef  long long slol;
typedef pair<int, int >pii;

#define MAX_VAL 100000000

#define MAX 2000024
#define NIL 0
#define INF (1<<28)

vector< int > G[MAX];
int left_sz, right_sz, match[MAX], dist[MAX];
// n: number of nodes on left side, nodes are numbered 1 to left_sz
// m: number of nodes on right side, nodes are numbered left_sz+1 to left_sz+right_sz
// G = NIL[0] U G1[G[1---n]] U G2[G[n+1---n+m]]

bool bfs() {
	int i, u, v, len;
	queue< int > Q;
	for (i = 1; i <= left_sz; i++) {
		if (match[i] == NIL) {
			dist[i] = 0;
			Q.push(i);
		}
		else dist[i] = INF;
	}
	dist[NIL] = INF;
	while (!Q.empty()) {
		u = Q.front(); Q.pop();
		if (u != NIL) {
			len = G[u].size();
			for (i = 0; i<len; i++) {
				v = G[u][i];
				if (dist[match[v]] == INF) {
					dist[match[v]] = dist[u] + 1;
					Q.push(match[v]);
				}
			}
		}
	}
	return (dist[NIL] != INF);
}

bool dfs(int u) {
	int i, v, len;
	if (u != NIL) {
		len = G[u].size();
		for (i = 0; i<len; i++) {
			v = G[u][i];
			if (dist[match[v]] == dist[u] + 1) {
				if (dfs(match[v])) {
					match[v] = u;
					match[u] = v;
					return true;
				}
			}
		}
		dist[u] = INF;
		return false;
	}
	return true;
}

int hopcroft_karp() {
	int matching = 0, i;
	// match[] is assumed NIL for all vertex in G
	while (bfs())
		for (i = 1; i <= left_sz; i++)
			if (match[i] == NIL && dfs(i))
				matching++;
	return matching;
}

int main() {

#if defined(_DEBUG)
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	int n, m;
	cin >> n >> m;

	if (n == 1 || m == 1)
	{
		cout << n *m;
		exit(0);
	}

	fi(i, 0, n)
	{
		fi(j, 0, m)
		{
			if ((i + j) % 2 != 0)
				continue;
			left_sz++;
		}
	}

	int curr_v = 1;
	int other_c = left_sz + 1;

	map<int, int> loc;

	fi(i, 0, n)
	{
		fi(j, 0, m)
		{
			if ((i + j) % 2 != 0)
				continue;

			for (int dx = -2; dx <= 2; dx++)
			{
				if (dx == 0) continue;
				for (int dy = -2; dy <= 2; dy++)
				{
					if (dy == 0 || abs(dx) == abs(dy)) continue;

					int x = i + dx, y = j + dy;
					if (x < 0 || y < 0 || x >= n || y >= m)
						continue;

					int v_id;
					if (loc.count(x * 1001 + y) > 0)
					{
						v_id = loc[x * 1001 + y];
					}
					else
					{
						loc[x * 1001 + y] = other_c;
						v_id = other_c;
						other_c++;
					}

					G[v_id].push_back(curr_v);
					G[curr_v].push_back(v_id);
				}
			}

			curr_v++;
		}
	}

	cout << hopcroft_karp();
}

#include <iostream>
using namespace std;

int main() {
  int m;
  int n;
  cin>>m>>n;
  if(m==1 || n==1)
    cout<<max(m,n);
  else if(m==2 || n==2)
    cout<<((m*n)/2)+1;
  else if(m%2==0 || n%2==0)
    cout<<(m*n)/2;
  else
    cout<<int((m*n)/2.0)+1;
}

#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <cmath>
#include <deque>

using namespace std;

#define pb push_back
#define sz size()
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
const int INF=~(1<<31);
const double EPS=0.0000001;

int main() {
#ifdef HOME
        freopen("input.txt","r",stdin);
        //freopen("output.txt","w",stdout);
#endif
        int n,m;
        cin>>n>>m;
        int r;
        if (min(n,m)==2) {
                r=max(n,m)/4*4;
                if (max(n,m)%4==1) r+=2;
                if (max(n,m)%4>2) r+=4;
                cout<<r<<endl;
                return 0;
        }
        if (min(n,m)==1) {
                cout<<max(n,m)<<endl;
                return 0;
        }
        if (min(n,m)==3) {
                r=max(n,m)/3*3;
                if (max(n,m)%3==0) r+=1;
                if (max(n,m)%3>0) r+=3;
                cout<<r<<endl;
                return 0;
        }
        r=max(n,m)/3;
		r=min(n,m)*r;
		int r1;
		r1=max(n,m)/3;
		r1=min(n,m)*r1;
        cout<<max(r,r1)<<endl;
        return 0;
}

#include <iostream>
#include <cmath>
#include <algorithm>
#include <limits>
#include <vector>
#include <bitset>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <time.h>
#include <map>
#include <stack>
#include <string>
#include <climits>
#include <ctime>
#include <fstream>
#include <sstream>
#include <set>
#include <queue>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define LD long double
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ABS(x) ((x)<0?-(x):(x))
#define si(n) scanf("%d",&n)
#define sf(n) scanf("%f",&n)
#define ss(n) scanf("%s",n)
#define pnl printf("\n")
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define FORR(i,n) for(int i=(n);i>=0;i--)
#define IT(Cf,it) for(typedef (Cf.begin()) i = Cf.begin();it!=Cf.end();it++)
#define DB(x) cout<<"\n"<<#x<<" = "<<(x)<<"\n";
#define SZ(a) (int)a.size()
#define pb push_back
#define CL(a,b) memset(a,b,sizeof(a))
#define GOLD ((1+sqrt(5))/2)
const double PI=3.14159265358979323846264338327950288419716939937510582097494459230;
void swaps (char *x,char *y){char temp;temp=*x;*x=*y;*y=temp;}
void swapi(int *a,int *b){int temp;temp=*a;*a=*b;*b=temp;}
ULL gcd(ULL a,ULL b){if(a==0)return b;if(b==0)return a;if(a==1||b==1)return 1;
if(a==b)return a;if(a>b)return gcd(b,a%b);else return gcd(a,b%a);}
bool vis[20][20];
int N,M;
bool check(int x,int y)
{
	return (x>=0&&y>=0&&x<N&&y<M);
}
int dx[] = {1,2,-1,-2,1,2,-1,-2};
int dy[] = {2,1,2,1,-2,-1,-2,-1};
int dfs(int idx,int idy)
{
	if(vis[idx][idy])
		return 0;
	vis[idx][idy] = true;
	int ans = 1;
	for (int i = 0; i < 8; i++) {
		int xi = idx + dx[i];
		int yi = idy + dy[i];
		if(check(xi,yi))
			ans+=dfs(xi,yi);
	}
	return ans;
}
int main()
{
    int Cases = 1;
//    si(Cases);
    for (int Case = 0; Case <Cases; Case++) {
	cin>>N>>M;
	if(N==1&&M==1)
		cout<<1<<endl;
	else if(N+M>=20)
		cout<<N*M/2 + (N*M)%2<<endl;
	else
	{
		int maxi = 0;
		if(min(N,M)==2)
		{
			cout<<max(N,M)<<endl;
			return 0;
		}
		maxi = dfs(0,0);
		cout<<maxi/2 + (maxi%2) <<endl;
	}
    }
    return 0;
}

#pragma comment(linker,"/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<cmath>
#include<vector>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

#define pi acos(-1.0)
#define eps 1e-10
#define pf printf
#define sf scanf
#define lson rt<<1,l,mi
#define rson rt<<1|1,mi+1,r
#define it rt,l,r
#define root 1,1,n
#define e tree[rt]
#define _s second
#define _f first
#define all(x) (x).begin,(x).end
#define mem(i,a) memset(i,a,sizeof i)
#define for0(i,a) for(int (i)=0;(i)<(a);(i)++)
#define for1(i,a) for(int (i)=1;(i)<=(a);(i)++)
#define mi ((l+r)>>1)
#define sqr(x) ((x)*(x))

const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int m,n;

int main()
{
    while(~sf("%d%d",&m,&n))
    {
        if(m>n)swap(m,n);
        if(m==1)pf("%d\n",n);
        else if(m==n&&m==2)
        {
            puts("4");
        }
        else if(m==2)
        {
            if(n&1)pf("%d\n",n+1);
            else pf("%d\n",n);
        }
        else
            pf("%d\n",(m*n+1)/2);
    }
    return 0;
}

#include <set>
#include <map>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = (int) 1e3 + 7;

const int di[] = {-2, -2, -1, -1, +1, +1, +2, +2};
const int dj[] = {-1, +1, -2, +2, -2, +2, -1, +1};

int ans;
int n, m;
int a[N][N];

void dfs(int i, int j, int c) {
  if (a[i][j]) {
    return;
  }

  a[i][j] = c;
  ans += c == 1;

  for (int k = 0; k < 8; k++) {
    int ni = i + di[k];
    int nj = j + dj[k];

    if (
      1 <= ni && ni <= n
      && 1 <= nj && nj <= m
    ) {
      dfs(ni, nj, 3 - c);
    }
  }
}

int main() {
  cin >> n >> m;

  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      dfs(i, j, 1);
    }
  }

  cout << ans << "\n";
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define F first
#define S second
#define pi 3.14159265359
#define EPS 1e-9
#define MOD 1000000007
void XsliferX(){ios::sync_with_stdio(0);ios_base::sync_with_stdio(0);cin.tie(0),cout.tie(0);}
ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x),y/2);else return (x*f_p((x*x),y/2));}
//int dx[9]= {1,-1,0,0,0,1,-1,1,-1};
//int dy[9]= {0,0,1,-1,0,1,-1,-1,1};
int dx[8]= {1,-1,2,-2,1,-1,2,-2};
int dy[8]= {2,2,1,1,-2,-2,-1,-1};
bool vis[1001][1001];
int n,m;
int bfs(int i,int j,bool f)
{
    int ans=0;
    queue <pair<int,int> > q;
    q.push({i,j});
    vis[i][j]=1;
    if(f)ans++;
    int u,v;
    while(!q.empty())
    {
        int siz=q.size();
        f=!f;
        while(siz--)
        {
            u = q.front().first;
            v = q.front().second;
            //cerr<<u<<" "<<v<<" "<<f<<endl;
            q.pop();
            int x,y;
            for(int k=0 ; k<8 ; k++)
            {
                x=u+dx[k],y=v+dy[k];
                if(x>=0&&y>=0&&x<n&&y<m&&!vis[x][y])
                {
                    vis[x][y]=1;
                    q.push({x,y});
                    if(f)ans++;
                }
            }
        }
    }
    return ans;
}
int main()
{
    XsliferX();
    cin>>n>>m;
    int ans=0;
    for(int i=0 ; i<n ; i++)
    {
        for(int j=0 ; j<m ; j++)
        {
            if(!vis[i][j])
                ans+=bfs(i,j,1);
        }
    }
    cout<<ans;
    return 0;
}
/*a=97  A=65
z=122 Z=90
0=48
prime number of ones in their binary representation
*/
// for(int i=0 ; i<n ; i++)
//ll f_p(ll x,int y){if (y==0)return 1;else if (y%2==0)return f_p((x*x)%MOD,y/2);else return (x*f_p((x*x)%MOD,y/2))%MOD;}
//freopen("output.txt","w",stdout);

#include <iostream>

using namespace std;
void swap(int &a, int &b)
{
	int t = a; a = b; b = t;
}
int main()
{
	int n, m;
	cin >> n >> m;
	if(m > n)
		swap(m, n);
	if(m == 2&&n==2)
	{
		cout << 4;
		return 0;
	}
	if(m==1)
	{
		cout << n;
		return 0;
	}
	if(m == 2&&n==3)
	{
		cout << 4;
		return 0;
	}
	if(m==2)
	{
		cout << n+1;
		return 0;
	}
	if(n%2==0||m%2==0)
	{
		cout << n*m/2;
		return 0;
	}
	cout << n*m/2+1;
}

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int main()
{
    int n,m,a,b,ta,tb;
    cin>>n>>m;
    if(n==1)
    {
        cout<<m<<endl;
        return 0;
    }
    if(m==1)
    {
        cout<<n<<endl;
        return 0;
    }
    if(n==2)
    {
        ta=m/4;
        tb=m%4;
        if(tb==1) cout<<ta*4+2<<endl;
        else if(tb>1) cout<<ta*4+4<<endl;
        else cout<<ta*4<<endl;
        return 0;
    }
    if(m==2)
    {
        ta=n/4;
        tb=n%4;
        if(tb==2) cout<<ta*4+2<<endl;
        else if(tb>1) cout<<ta*4+4<<endl;
        else cout<<ta*4<<endl;
        return 0;
    }
    int t=n*m;
    if(t&1)
        cout<<(t+1)/2<<endl;
    else
        cout<<t/2<<endl;
    return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <iomanip>
#include <string>
#include <memory.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <functional>
#include <numeric>

using namespace std;
#define LL long long

int main(){
#ifdef _DEBUG
    freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
#endif
    int n, m;
    cin >> n >> m;
    if (n == 1)
    {
        cout << m;
        return 0;
    }
    if (m == 1)
    {
        cout << n;
        return 0;
    }
    if (m == 2 && n == 2)
    {
        cout << 4;
        return 0;
    }

    if (m == 2 && n%2==1)
    {
        cout << m*n / 2 + 1;
        return 0;
    }
    if (n == 2 && m % 2 == 1)
    {
        cout << m*n / 2 + 1;
        return 0;
    }
    int s = n*m;
    int ans = s / 2;
    if (s % 2 == 1) ans++;
    cout << ans;
    return 0;
}

// @snippet<sh19910711/contest:headers.cpp>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <limits>
#include <complex>
#include <functional>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>

// @snippet<sh19910711/contest:solution/interface.cpp>
namespace solution {
  class SolutionInterface {
  public:
    virtual int run() = 0;

  protected:
    virtual void pre_calc() {}
    virtual bool action() = 0;
    virtual void init() {};
    virtual bool input() { return false; };
    virtual void output() {};

    SolutionInterface() {}

  private:

  };
}

// @snippet<sh19910711/contest:solution/solution-base.cpp>
namespace solution {
  class SolutionBase: public SolutionInterface {
  public:
    virtual int run() {
      pre_calc();
      while ( action() );
      return 0;
    }

  };
}

// @snippet<sh19910711/contest:solution/typedef.cpp>
namespace solution {
  typedef std::istringstream ISS;
  typedef std::ostringstream OSS;
  typedef std::vector<std::string> VS;
  typedef long long LL;
  typedef int INT;
  typedef std::vector<INT> VI;
  typedef std::vector<VI> VVI;
  typedef std::pair<INT,INT> II;
  typedef std::vector<II> VII;
}

// @snippet<sh19910711/contest:solution/namespace-area.cpp>
namespace solution {
  // namespaces, types
  using namespace std;

}

// @snippet<sh19910711/contest:solution/variables-area.cpp>
namespace solution {
  // constant vars

  // storages
  int n, m;
  int result;
}

// @snippet<sh19910711/contest:solution/solver-area.cpp>
namespace solution {
  class Solver {
  public:
    void solve() {
      result = 0;
      if ( n == 2 ) {
        if ( m % 4 == 3 ) {
          result = m + 1;
        } else {
          result = m + m % 4;
        }
      }
      if ( m == 2 ) {
        if ( n % 4 == 3 ) {
          result = n + 1;
        } else {
          result = n + n % 4;
        }
      }
      result = max(result, (int)( ( n * m + 1.0 ) / 2 ));
    }

  private:

  };
}

// @snippet<sh19910711/contest:solution/solution.cpp>
namespace solution {
  class Solution: public SolutionBase {
  public:
  protected:
    virtual bool action() {
      init();
      if ( ! input() )
        return false;
      solver.solve();
      output();
      return true;
    }

    bool input() {
      return cin >> n >> m;
    }

    void output() {
      cout << result << endl;
    }

  private:
    Solver solver;

  };
}

// @snippet<sh19910711/contest:main.cpp>
#ifndef __MY_UNIT_TEST__
int main() {
  return solution::Solution().run();
}
#endif

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

int main(){
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);

	int n,m;

	cin>>n>>m;

	if(n>m)swap(n,m);

	if(n==1){cout<<m;return 0;}
	if(n==2 && m<=4){cout<<4;return 0;}
	if(n==3 && m<4){cout<<5;return 0;}
	int ans=n*m/2+(n*m)%2;
	cout<<ans;

}

/************* yogesh sharma *****************/
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <limits.h>

using namespace std;

#define rep(i,a,b) for(typeof(a) i=(a);i<(b);i++)
#define ll long long int
#define ii pair<int,int>
#define Clear(x,val) memset(x,val,sizeof(x))
#define SZ(v) (v).size()

int main()
{
	int n , m;
	cin >> n >> m;
	int ans1 = 0 , ans2 = 0 , ans3 = 0 , ans4 = 0;

	int add = 1;

	rep( i ,0 , n ) {
		ans1 += (m/2);
		if( m&1 ){  ans1 += add; add = !add; }
	}

	if( n == 1 || m == 1 ) ans1 = max( n , m );
	cout << max( ans1 , ans2 ) << "\n";
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef vector< pii > vii;
#define INF 0x3f3f3f3f

int D[1030][1030];

int main(){
	int n,m;
	cin>>n>>m;
	if(n==1 || m==1  ){
		cout<<n*m<<endl;
		return 0;
	}
	if(n*m<9){
		cout<<4<<endl;
		return 0;
	}

	n=n*m;
	if(n%2==1)n++;
	cout<<n/2<<endl;
	return 0;
}

// eddy1021
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long ll;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
typedef pair<LD,LD> Pt;
typedef tuple<int,int,int> tiii;
typedef tuple<LL,LL,LL> tlll;
#define mod9 1000000009ll
#define mod7 1000000007ll
#define INF  1023456789ll
#define INF16 10000000000000000ll
#define FI first
#define SE second
#define X FI
#define Y SE
#define PB push_back
#define MP make_pair
#define MT make_tuple
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(...)
#endif
inline ll getint(){
  ll _x=0,_tmp=1; char _tc=getchar();
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline ll add( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x + _y;
  if( _ >= _mod ) _ -= _mod;
  return _;
}
inline ll sub( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x - _y;
  if( _ < 0 ) _ += _mod;
  return _;
}
inline ll mul( ll _x , ll _y , ll _mod = mod7 ){
  ll _ = _x * _y;
  if( _ >= _mod ) _ %= _mod;
  return _;
}
ll mypow( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 1ll;
  ll _tmp = mypow( _a , _x / 2 , _mod );
  _tmp = mul( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = mul( _tmp , _a , _mod );
  return _tmp;
}
ll mymul( ll _a , ll _x , ll _mod ){
  if( _x == 0 ) return 0ll;
  ll _tmp = mymul( _a , _x / 2 , _mod );
  _tmp = add( _tmp , _tmp , _mod );
  if( _x & 1 ) _tmp = add( _tmp , _a , _mod );
  return _tmp;
}
inline bool equal( D _x ,  D _y ){
  return _x > _y - eps && _x < _y + eps;
}
int __ = 1 , _cs;
/*********default*********/
void build(){

}
ll xn , xm;
void init(){
  xn = getint();
  xm = getint();
}
inline ll cal( ll n , ll m ){
  ll tx = ( ( n + 1 ) / 2 ) * ( ( m + 1 ) / 2 );
  ll ty = ( n / 2 ) * ( m / 2 );
  return tx + ty;
}
void solve(){
  ll ans = max( cal( xn , xm ) , cal( xm , xn ) );
  cout << ans << endl;
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}

#include <stdio.h>
#include <bits/stdc++.h>

using namespace std;

#include <x86intrin.h>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
template <typename T> using ordered_set = tree<T, null_type, std::less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define all(x) x.begin(), x.end()

#define mp make_pair
#define in insert
#define er erase
#define sc scanf
#define pr printf
#define con continue
#define pb push_back
#define sc scanf
#define pr printf
#define up upper_bound
#define lb lower_bound
#define s second
#define f first
#define int long long

const long long infl = 1e18;
const int N = 3e5 + 300, N2 = 2e3, inf = 1e9 + 200;

set <int> S;
vector <int> g;
int n, m, k;
int a[N];
string ss;

main (){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	int val = 0;
	if (n > 1 && m > 1) val = 4;
	cout << max({(n + 2) / 3 * m, (m + 2) / 3 * n, val});

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
int n,m;
int main(){
	scanf("%d %d", &n, &m);
	printf("%d\n", max((min(n,m)/3 + (min(n,m)%3)!=0) * max(n,m), (max(n,m)/3+ (max(n,m)%3)!=0) * min(n,m)));
}

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;

int main(){
    int n,m;
    cin>>n>>m;
    cout<<max((n/4+1)*m , (m/4+1)*n)<<endl;

}

#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <sstream>
#include <string>
#include <bitset>
#include <vector>
#include <deque>
#include <queue>
#include <list>
#include <map>
#include <set>

#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;
typedef pair< int, int > pii;
typedef vector< int > vint;
typedef vector< int64 > vint64;

#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define forn(i, n) for (int i = 0; i < (n); ++i)
#define forr(i, n) for (int i = (n) - 1; i >= 0; --i)

const int UNDEF = -1;
const int INF = 2000000000;
const double EPS = 1e-9;
const double PI = 3.1415926535897932384626433832795;

template< typename T >
T sqr(const T &x)
{
	return x * x;
}

template< typename T >
string GetString(const T &val)
{
	ostringstream sout;
	sout << val;
	return sout.str();
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("B.txt", "r", stdin);
#endif

	int64 n, m;
	cin >> n >> m;

	if (n > m) swap(n, m);

	int64 res = 0;
	if (n == 2 && m == 2)
		res = n * m;
	else if (n < 2 && m <= 10)
	{
		res = 5;
	}
	else
		res = (n * m + 1) / 2;
	cout << res << endl;

	return 0;
}

#include<bits/stdc++.h>
typedef long long ll;
#define M 1000000007
#define endl "\n"
#define rep(a,b,in) for(int i=a;i<b;i+=in)
#define int long long
using namespace std;
int32_t main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    int n,m;
    cin>>n>>m;
    cout<<(n*m)/2+(n*m)%2;
}

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <numeric>
#include <limits>
#include <string.h>

 //#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long LL;
#define DEBUG(x) cout << '>' << #x << ':' << x << endl;
#define DEBUG(x,y) cout << '>' << #x << ':' << x <<" "<< #y << ':' << y << endl;
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<LL>::max()
#define lmin numeric_limits<LL>::min()

int main()
{
    LL n, m;
    cin>>n>>m;
    LL ans=0;
    if (n < m){
        swap(n, m);
    }
    if (m == 1){
        cout<<n<<"\n";
    } else if(m == 2){
        ans=0;
        for (int i=0;i<m;i++){
            if (i%4 < 2){
                ans += 2;
            }
        }
        cout<<ans<<"\n";
    } else {
        cout<<(m*n+1)/2;
    }
    return 0;

}

#include <iostream>

using namespace std;

int N,M;

int main()
{
    cin >> N >> M;
    if (min(N,M)==1)
    {
        cout << max(N,M) << endl;
        return 0;
    }
    cout << (N*M)/2+(N*M)%2 << endl;
    return 0;
}

#include <iostream>
#include <cmath>
#include <algorithm>
#include <limits>
#include <vector>
#include <bitset>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <time.h>
#include <map>
#include <stack>
#include <string>
#include <climits>
#include <ctime>
#include <fstream>
#include <sstream>
#include <set>
#include <queue>
using namespace std;
#define LL long long
#define ULL unsigned long long
#define LD long double
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)<(b)?(a):(b))
#define ABS(x) ((x)<0?-(x):(x))
#define si(n) scanf("%d",&n)
#define sf(n) scanf("%f",&n)
#define ss(n) scanf("%s",n)
#define pnl printf("\n")
#define REP(i,n) for(int i=0;i<(n);i++)
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define FORR(i,n) for(int i=(n);i>=0;i--)
#define IT(Cf,it) for(typedef (Cf.begin()) i = Cf.begin();it!=Cf.end();it++)
#define DB(x) cout<<"\n"<<#x<<" = "<<(x)<<"\n";
#define SZ(a) (int)a.size()
#define pb push_back
#define CL(a,b) memset(a,b,sizeof(a))
#define GOLD ((1+sqrt(5))/2)
const double PI=3.14159265358979323846264338327950288419716939937510582097494459230;
void swaps (char *x,char *y){char temp;temp=*x;*x=*y;*y=temp;}
void swapi(int *a,int *b){int temp;temp=*a;*a=*b;*b=temp;}
ULL gcd(ULL a,ULL b){if(a==0)return b;if(b==0)return a;if(a==1||b==1)return 1;
if(a==b)return a;if(a>b)return gcd(b,a%b);else return gcd(a,b%a);}
bool vis[20][20];
int N,M;
bool check(int x,int y)
{
	return (x>=0&&y>=0&&x<N&&y<M);
}
int dx[] = {1,2,-1,-2,1,2,-1,-2};
int dy[] = {2,1,2,1,-2,-1,-2,-1};
int dfs(int idx,int idy)
{
	if(vis[idx][idy])
		return 0;
	vis[idx][idy] = true;
	int ans = 1;
	for (int i = 0; i < 8; i++) {
		int xi = idx + dx[i];
		int yi = idy + dy[i];
		if(check(xi,yi))
			ans+=dfs(xi,yi);
	}
	return ans;
}
int main()
{
    int Cases = 1;
//    si(Cases);
    for (int Case = 0; Case <Cases; Case++) {
	cin>>N>>M;
	if(N>M)
		swap(N,M);
	if(N==1)
		cout<<M<<endl;
	else if(N+M>=20)
		cout<<N*M/2 + (N*M)%2<<endl;
	else
	{
		int maxi = 0;
		if(min(N,M)==2)
		{
			cout<<max(N,M)<<endl;
			return 0;
		}
		maxi = dfs(0,0);
		cout<<maxi/2 + (maxi%2) <<endl;
	}
    }
    return 0;
}

/** By @ZhakudaMagzhan **/
#include <bits/stdc++.h>
#include <stdio.h>
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#define x1 qeerdx
#define y1 qeerdy

#define lb lower_bound
#define ub upper_bound

#define endl '\n'
#define fast_in ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);

#define mp  make_pair
#define pb  push_back

#define fi first
#define se second

#define wk exit (0);
#define   sz(x)  (int)x.size()
#define  all(x)  x.begin(), x.end()
#define  bit(x)  __builtin_popcountll(x)

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

typedef vector <int> vi;
typedef pair <int,int> pii;

const int inf = (int) 2e9+99999, mod = (int)1e9+7;
const ll linf = (ll) 2e18+99999;

int kob (int x, int y) { return ((ll)x * y) % mod; }
int aza (int x, int y) { x -= y; if (x < 0) return x + mod; return x; }
int kos (int x, int y) { x += y; if (x >= mod) return x - mod; return x; }

const int maxn = (int) 1e5 + 777, maxn2 = (int) 2e6;

int main () { fast_in;
    #ifdef lcl
    freopen (".in", "r", stdin);
	freopen (".out", "w", stdout);
	#endif
	int n, m;
	cin >> n >> m;
	int ans1 = 0, ans2 = 0;

	for (int i = 1; i <= n; i += 3) {
		ans1 += m;
	}
	for (int i = 1; i <= m; i += 3) {
		ans2 += n;
	}

	if (n == 3 && m == 3) {
		cout << 5;
	}
	else if (n == 3 && m == 5) {
		cout << 8;
	}
	else if (n == 3 && m == 6) {
		cout << 9;
	}
	else {
		cout << max (ans1, ans2);
	}

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2050;

long long solve(long long n, long long m){
    if(n == 1) return m;
    if(n == 2) return 2LL * (m / 4) + 2LL * min(2LL, m % 4);
    return (n / 2 + ((n % 2) > 0)) * (m / 2 + m % 2) + (m / 2)*((n - 1)/ 2 + (((n - 1)% 2) > 0));
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    long long n, m;
    cin >> n >> m;
    cout << max(solve(n, m), solve(m, n)) << '\n';
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
int solve(int n,int m){
    if(n==2&&m==2)
        return 4;
    int now = (n*(m/3+(m%3!=0)));
    if(n==3){
        if(m%3==0)
            now+=2;
        if(m%3==2)
            now+=1;
    }
    if(n==5){
        if(m%3!=1)
            now++;
    }
    return now;
}
int main(){
    int n,m;
    cin>>n>>m;
    cout<<max(solve(n,m),solve(n,m))<<endl;
}

#include <iostream>

using namespace std;

int main()
{
    int a,b;
    cin>>a>>b;

    if( a == 1 )
    {
        cout<<b;
        return 0;
    }

    if( b == 1 )
    {
        cout<< a;
        return 0;
    }
    int count = 0;
    for(int i = 0 ; i < b ; i++)
    {
        if( i % 2 == 0 )
        {
            for(int j = 0 ; j < a ; j+=2 ) count++;
        }
        else
        {
            for(int j = 1; j< a ; j+=2) count++;
        }

    }

    cout<<count;
    return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <iomanip>
#include <sstream>
#include <utility>
#include <string>
#include <vector>
#include <list>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cmath>
#include <ctime>
#include <assert.h>
#include <string.h>
#include <limits>
using namespace std;

#define INF 100000000
#define PI 3.1415926535897932384626433832795
#define PI_HALF 1.570796327
#define EPS 1e-9

typedef unsigned int UI;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair< int, int > PII;
typedef pair< LL, LL > PLL;
typedef vector< int > VI;
typedef vector< LL > VLL;
typedef vector< string > VS;
typedef vector< PII > VPII;
typedef vector< PLL > VPLL;

#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define SZ(c) (int)(c).size()
#define ALL(c) (c).begin(), (c).end()
#define SORT(c) sort( ALL( c ) )
#define SORT_(c,f) sort( ALL( c ), f )
#define FILL(x,v) memset( x, v, sizeof( x ) );

#define REP(i,n) for ( int i = 0, max_ = (n); i < max_; ++i )
#define REPD(i,n) for ( int i = (n) - 1; i >= 0; --i )
#define FOR(i,a,b) for ( int i = (a), max_ = (b); i < max_; ++i )
#define FORD(i,a,b) for ( int i = (a) - 1, min_ = (b); i >= min_; --i )

LL GCD ( LL a, LL b ) { return b != 0 ? GCD(b, a % b) : a; }
LL LCM ( LL a, LL b ) { return a*(b / GCD(a,b)); }
LL Pow ( LL n, LL e ) { if ( e == 0 ) return 1; if ( e == 1 ) return n; else if ( e & 1 ) { LL t = Pow(n,e/2); return n*t*t; } else { LL t = Pow(n,e/2); return t*t; } }

int main ()
{
    int N, M;
    scanf( "%d %d", &N, &M );

    int res = 0;
    if ( N == 1 )
        res += M;
    else if ( M == 1 )
        res += N;
    else
    {
        res += (M/2 + (M&1))*(N/2 + (N&1));
        res += (M/2) * (N/2);
    }

    if ( N == 2 && M == 2 )
    {
        res = 4;
    }
    else if (
        (N == 2 && (M&1) ) ||
        (M == 2 && (N&1) )
        )
    {
        ++res;
    }
    else if (
        (N == 2 && (M % 2 == 0) ) ||
        (M == 2 && (N % 2 == 0) )
        )
    {
        res += 2;
    }
    printf( "%d\n", res );

    return 0;
}

#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>

#define speedio ios_base::sync_with_stdio(false); cin.tie(NULL);
#define pretime float(clock()-clk)/CLOCKS_PER_SEC
#define max2(a,b) ((a)>(b) ? (a) : (b))
#define min2(a,b) ((a)<(b) ? (a) : (b))
#define rep(i,a,b) for(i=a;i<=b;++i)
#define rev(i,a,b) for(i=a;i>=b;--i)
#define lli long long int
#define vll vector<lli>
#define vi vector<int>
#define sll set<lli>
#define si set<int>
#define pll pair<lli,lli>
#define pii pair<int,int>
#define ins insert
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define inf LLONG_MAX
#define PI 3.14159265
#define mod 1000000007
clock_t clk=clock();

using namespace std;
int i,j;
void solve(void);

int main()
{
  speedio;
   int t=1;
  // cin>>t;
   while(t--)
     solve();

  return 0;
}
//
void solve()
{
	int n,m; cin>>n>>m;
	if(n==1)  cout<<"\n"<<m;
	else if(m==1) cout<<"\n"<<n;
	else
     cout<<"\n"<<(n*m)/2+(n*m)%2;

}

#include <iostream>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
#include <cassert>
using namespace std;

#define speed ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define int long long int
#define pi pair<int,int>
#define pb push_back
#define fi first
#define se second
#define inf 2e9+9
#define mod 1000000007
#define endl "\n"

const int N = 50;

signed main(){
//	freopen("input.txt","r",stdin);
	speed;
	int n,m;
	cin>>n>>m;
	if(n == 1 || m == 1)
		return cout<<n+m-1,0;
	cout<<(n*m+1)/2;
	return 0;
}

#pragma comment(linker, "/STACK:100000000000000")
#include <stdio.h>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string.h>
#include <cctype>
#include <cassert>
#include <ctime>
#define mp make_pair
#define pb push_back
#define lo long long int
#define pi 3.14159265358979323
#define eps 1e-6
#define MN 200
using namespace std;
const lo INF= 2e18;
bool er[MN];
int main()
{
	//freopen("input.txt", "r", stdin);
	lo n, m;
	cin >> n >> m;
	if(n > m) swap(n, m);
	if(n == 1)
	{
		cout << m;
		return 0;
	}
	if((m & 1) && (n & 1))
	{
		cout << (n / 2 + 1) * (m / 2 + 1) + (n / 2) * (m / 2);
		return 0;
	}
	if(n & 1) swap(n, m);
	cout << n / 2 * m;
}

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>

using namespace std;
int n , m;
int get(int x)
{
   if (x % 3 == 0) return x/3;
     else return x/3 + 1;
}

int main()
{
   cin >> n >> m;
   if (get(n) * m < get(m) * n) swap(n , m);
   cout << get(n) * m << endl;
}

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <sstream>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <numeric>
#include <utility>

using namespace std;

#define Rep(i,n) for(int i = 0; i < n; ++i)
#define Rep2(i, f, t) for(int i = (f); i <= (t); ++i)
#define tr(C,it) for(__typeof__((C).begin()) it = (C).begin(); it != (C).end(); ++it)

int n,m;

int cal(int x, int y) {
	if(x==1) return y;
	if(x==2) {
		if(y % 3==0)return y / 3 * 2 + 2;
		return y / 3 * 2 + 2 * (y % 3);
	}
	if(x==3) {
		int ans = y / 3 * 3;
		if( y % 3 > 0)ans += 3;
		if( y % 3 > 1)ans += 1;
		return ans;
	}
	return max(x / 3 * y, y / 3 * x);
}

int main() {
	cin>>n>>m;
	if(n>m)swap(n,m);
	cout<<cal(n, m)<<endl;
	return 0;
}

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <fstream>
#include <sstream>
#include <map>
#include <set>
#include <numeric>
#include <limits>
#include <string.h>

 //#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long LL;
#define DEBUG(x) cout << '>' << #x << ':' << x << endl;
#define DEBUG(x,y) cout << '>' << #x << ':' << x <<" "<< #y << ':' << y << endl;
#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<LL>::max()
#define lmin numeric_limits<LL>::min()

int main()
{
    LL n, m;
    cin>>n>>m;
    if (n ==1){
        cout<<m<<"\n";
        return 0;
    }
    if (m ==1){
        cout<<n<<"\n";
        return 0;
    }
    if (n < m){
        swap(n,m);
    }

    if (m == 2){
        if (n == 2 || n == 4 ){
            cout<< n <<"\n";
            return 0;
        }
        if (n == 3 ){
            cout<< 4<<"\n";
            return 0;
        }

        LL ans=0;
        ans = 4*(n/4) + 2*(n%4);
        cout<<ans<<"\n";
        return 0;
    }
    if (m >= 3){
        LL ans;
        if (m%2 == 0 || n%2==0){
            ans = (m*n)/2;
        } else {
            ans = ((n-1)*m)/2;
            ans += (m+1)/2;
        }
        cout<<ans<<"\n";
    }

    return 0;
}

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

#define sd(mark) scanf("%d",&mark)
#define ss(mark) scanf("%s",mark)
#define sl(mark) scanf("%lld",&mark)
#define clr(mark) memset(mark,0,sizeof(mark))

#ifndef strange
#define trace(...)
#define endl '\n'
#define start_routine()
#define end_routine()
#endif
typedef long long ll;
//__gcd

#define mod 1000000007
#define F first
#define S second
#define mp make_pair
#define sz(x)  (long long (x.size()))

#define pb push_back
// #define int long long
//memset(dp,0x3f,sizeof(dp));
int n,m;

signed main(){
    int t=1;
    start_routine();
    cin.tie(0); cout.tie(0);
    ios_base::sync_with_stdio(NULL);

    // cin>>t;
    while(t-->0){

        sd(n);sd(m);
        if(n==1 || m==1){
            cout<<(n*m);
        }
        else if((n==2 && m==2)){
            cout<<"4\n";
        }
        else if(n==2){
            if(m%2==0){
                cout<<m;
            }
            else{
                cout<<m+1;
            }
        }
        else if(m==2){
            if(n%2==0){
                cout<<n;
            }
            else{
                cout<<n+1;
            }
        }
        else {
            int ans=0,ans1=0;
            ans=((m/2)*n);
            if(m%2==0){
            }
            else{
                ans+=ceil(n/(double)2);
            }

            ans1=(n/2)*m;
            if(n%2==0){

            }
            else{
                ans1+=ceil(m/(double)2);
            }
            cout<<max(ans,ans1);
        }

    }

    end_routine();
    return 0;
}

//check check
#include<iostream>
#include<vector>
#include<algorithm>
#include<fstream>
#include<queue>
#include<cstring>

#define ll long long
#define pb(x) push_back(x)

using namespace std;

const int NMAX = 0;

int main()
{
    int n,m,i,j;

    cin>>n>>m;

    if(n == 1)
    {
        cout<<m;
        return 0;
    }
    if(m == 1)
    {
        cout<<n;
        return 0;
    }
    if(n == 2 )
    {
        cout<<m+1 + (m%2 == 0);
        return 0;
    }
    if(m == 2)
    {
        cout<<n+1 + (n%2 == 0);
        return 0;
    }

    int sum = 0;
    for(i = 1 ; i <= n ; ++i)
    {
        for(j = 1 ; j <= m ; ++j)
        {
            if(i&1)
            {
                //imparele
                if(j&1)
                    sum++;
            }
            else
            {
                //parele
                if(!(j&1))
                    sum++;
            }
        }
    }

    int sum1 = 0;

    for(i = 1 ; i <= n ; ++i)
    {
        for(j = 1 ; j <= m ; ++j)
        {
            if(i&1)
            {
                if(!(j&1))
                    sum1++;
            }
            else
            {
                if(j&1)
                    sum1++;
            }
        }
    }

    cout<<max(sum , sum1);
}

#include <cstdio>
#include <iostream>

#include <string>
#include <vector>
#include <deque>
#include <set>
#include <map>

#include <algorithm>
#include <utility>
#include <functional>

using namespace std;

int main()
{
    ios_base::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    cout << max((n + 2) / 3 * m, (m + 2) / 3 * n) << endl;

    return 0;
}

#include <cstdio>

int n, m;
bool knight[1000][1000];
int dx[] = {-2, -2, -1, 1, 2, 2, 1, -1};
int dy[] = {-1,  1,  2, 2, 1,-1,-2, -2};
int main()
{
	scanf("%d %d", &n, &m);
	for(int i = 0;i < n;++i)
		for(int j = 0;j < m;++j)
			if((i + j) % 2 == 0)
				knight[i][j] = 1;
	for(int i = 0;i < n;++i)
		for(int j = 0;j < m;++j)
			if(!knight[i][j])
			{
				bool valid = 1;
				for(int k = 0;k < 8;++k)
				{
					int x = i + dx[k];
					int y = j + dy[k];
					if(x < 0 || x >= n)
						continue;
					if(y < 0 || y >= m)
						continue;
					if(knight[x][y])
						valid = 0;
				}
				knight[i][j] = valid;
			}
	int sum = 0;
	for(int i = 0;i < n;++i)
		for(int j = 0;j < m;++j)
			sum += knight[i][j];
	if(n == 2 || m == 2)
	{
		if(n > m)
		{
			int t = n;
			n = m;
			m = t;
		}
		int temp = 0;
		for(int i = 0;i < m;i += 4)
			if(i + 1 >= m)
				temp += 2;
			else
				temp += 4;
		if(temp > sum)
			sum = temp;
	}
	printf("%d\n", sum);
}

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <algorithm>
#include <set>
#include <functional>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9 + 5;
const int MAXN = 1005;
const int MOD = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1.0);
LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a%b); }
LL ppow(LL a, LL b) { LL res = 1; for (int i = 1; i <= b; i++)	res *= a; return res; }
LL quick_mod(LL a, LL b, LL c) { LL ans = 1; while (b) { if (b % 2 == 1)ans = (ans*a) % c; b /= 2; a = (a*a) % c; }return ans; }

int main()
{
	int n, m;
	int ans;
	while (scanf("%d%d",&n,&m)!=EOF)
	{
		if (n == 1 || m == 1)
			printf("%d\n", n > m ? n : m);
		else if (n == 2 && m != 2)
		{
			ans = (m-1) / 4;
			ans = ans * 2;
			if (m % 4 == 1)
				ans += 1;
			else
				ans += 2;
			ans *= 2;
			printf("%d\n", ans);
		}
		else if (n != 2 && m == 2)
		{
			ans = n / 4;
			ans = ans * 2;
			if (n % 4 == 1)
				ans += 1;
			else
				ans += 2;
			ans *= 2;
			printf("%d\n", ans);
		}
		else if (m % 2 == 1 && n % 2 == 1)
		{
			ans = m*(n / 2) + (m + 1) / 2;
			printf("%d\n", ans);
		}
		else
		{
			printf("%d\n", m*n / 2);
		}
	}
}

#include <bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
typedef long long ll;

#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,it) for(typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
#define present(c,val) ((c).find(val) != (c).end())
#define cpresent(c,val) (find(all(c),val) != (c).end())
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define FOR(i, x, y) for(int i= (x); i<= (y); ++i)
#define FORR(i, y, x) for(int i= (y); i>= (x); --i)

#define imax numeric_limits<int>::max()
#define imin numeric_limits<int>::min()
#define lmax numeric_limits<ll>::max()
#define lmin numeric_limits<ll>::min()
#define debug(var) cerr<<#var<<" = "<<(var)<<endl;
#define debugarr(var,n) cerr<<#var<<" = { ";rep(i,n) cerr<<var[i]<<" ";cerr<<"}"<<endl;
#define debugmat(var,m,n) cerr<<#var<<" = \n";rep(i,m) {rep(j,n) cerr<<var[i][j]<<" ";cerr<<endl;}
#define sci(var) scanf("%d",&(var))
#define scll(var) scanf("%lld",&(var))
#define MOD ((int)1e9+7)

int main() {
	int m,n;cin>>m>>n;
	if(m>n) swap(m,n);
	if(m==1) {cout<<n<<endl;return 0;}
	if(m==2) {cout<<4*(n/4)+2*min(2,n%4)<<endl;return 0;}
	if(m==3 && n==3) {cout<<4<<endl;return 0;}
	cout<<m*n-(m*n)/2<<endl;
	return 0;
}

#define GLIBCXX_DEBUG
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <string>
#include <string.h>

using namespace std;

int n, m;

int main()
{
  #ifndef ONLINE_JUDGE
  freopen("a.in", "r", stdin);
  freopen("a.out", "w", stdout);
  #endif

  scanf("%d%d", &n, &m);

  if (n == 1 || m == 1)
  {
    printf("%d", n * m);
    exit(0);
  }

  if ((n * m) % 2 == 0) printf("%d", (n * m) / 2);

  if ((n * m) % 2 == 1) printf("%d", (n * m) / 2 + 1);

  return 0;
}

#include<iostream>
#include<stdio.h>
using namespace std;

int main() {
	int n, m;
	scanf("%d%d", &n, &m);
	if (n == 1 || m == 1)printf("%d", max(n, m));
	else if (n == 7 && m == 2 || n == 2 && n == 7)printf("8");
	else {
		int a = n >> 1, b = n & 1, c = m >> 1, d = m & 1;
		printf("%d", max((a + b)*(c + d) + a*c, 4));
	}
}

#include <string>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <sstream>
#include <bitset>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <fstream>
#include <math.h>
#include <cstdlib>
#include <ctime>
#include <algorithm>
#include <vector>
#include <set>
#include <complex>
#include <list>
#include <valarray>
#include <memory.h>
#include <sstream>
#include <string>

using namespace std;

#define all(n) (n).begin(),(n).end()
#define rall(n) (n).rbegin(),(n).rend()
#define mp make_pair
#define pb push_back
#define sz size()
#define F first
#define S second
#define FO(i,x) for(int i=0;i<x;i++)

#define READ(s) freopen(s, "r", stdin)
#define WRITE(s) freopen(s, "w", stdout)
  int dx[]={-2,-2,-1,-1,1,1,2,2}; int dy[]={-1,1,-2,2,-2,2,-1,1}; // Knight Dir
//  int dx[]={-1,-1,-1,0,1,1,1,0}; int dy[]={-1,0,1,1,1,0,-1,-1};  // 8 Dir
//  int dx[]={0,1,-1,0}; int dy[]={1,0,0,-1}; // 4 Dir
int n,m;
int arr[1009][1009];
bool valid(int x,int y){
     return !( x<0||y<0||x>=n||y>=m);
}
int mx(){
    int res=0;
    memset(arr,0,sizeof(arr));
    for(int i=0;i<n;i++)
      if(i%3==0){
          for(int j=0;j<m;j++)
          {
              arr[i][j]=1;
              res++;
              for(int k=0;k<8;k++)
                 if(valid(i+dx[k],j+dy[k]))
                    arr[i+dx[k]][j+dy[k]]=-1;
          }
      }
    FO(i,n) FO(j,m)
      if(arr[i][j]==0) {
          res++;
          arr[i][j]=1;
           for(int k=0;k<8;k++)
                 if(valid(i+dx[k],j+dy[k]))
                    arr[i+dx[k]][j+dy[k]]=-1;
      }
      return res;
}
int main(){
  //   READ("in.txt");
       cin>>n>>m;
       int res=mx();
       swap(n,m);
       cout<<max( res,mx() )<<endl;
       return 0;
}

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define ld long double
#define ll long long int
#define pb push_back
#define mod 1000000007
#define inarr(i,arr,n); for(ll i=0;i<n;i++) cin >> arr[i];
#define outarr(i,arr,n); for(ll i=0;i<n;i++) cout<<arr[i]<<' ';
#define swap(a,b,t) {t=a;a=b;b=t;}
#define ve vector
#define sz(a) (int)((a).size())
#define fi first
#define se second
#define pa pair
#define fastio  {ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);}
#define ll long long int
#define fr(i, a, b) for (int i = a; i <= b; i++)
#define frn(i, a, b) for (int i = a; i >= b; i--)
#define mk make_pair
#define endl "\n"
#define setvector(vname,value,size); for(int i=0;i<size;i++)vname[i]=value;
const ll inf = 9e18;
//cout << fixed << setprecision(9) << ans <<endl; for accurate decimal precision.
int main()
{
    //fastio
    ll n, m;
    cin>>n>>m;
    if(n>m)
    {
        int _t;
        swap(n, m,_t);
    }
    if(n<=2)
    {
        cout<<m<<endl;
    }
    else
    {
        cout<<max((n/2)*m, (m/2)*n)<<endl;
    }
}

#include <iostream>

using namespace std;

int main()
{
    int a,b;
    cin>>a>>b;

    for(int i = 0 ; i < 8000000 ; i++)
    {

    }

    cout<<4;
    return 0;
}

#include<iostream>
using namespace std;
#define ll long long int
ll ceil(ll a, ll b){
    return a/b + (a%b!=0);
}

int main(){
    ll n,m;
    cin>>n>>m;
    cout<<max( m*ceil(n,3) , n*ceil(m,3))<<endl;
}

#include <cstdio>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <limits>
#include <utility>
#include <numeric>
#include <iterator>
#include <algorithm>
using namespace std;

const int INF=(1<<30)-1;
const long long LINF=(1ll<<62)-1;
const int DIRX[]={-1,0,0,1,-1,-1,1,1}, DIRY[]={0,-1,1,0,-1,1,-1,1};
const double ERR=1e-11, PI=(2*acos(0.0));

#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)<(b)?(b):(a))
template<class T> inline T MIN(T a,T b) {return ((a<b)?(a):(b));}
template<class T> inline T MAX(T a,T b) {return ((b<a)?(a):(b));}
template<class T> inline T ABS(T a) {return ((a<0)?(-a):(a));}
template<class T> inline void checkMIN(T& a,T b) {if(b<a) a=b;}
template<class T> inline void checkMAX(T& a,T b) {if(a<b) a=b;}
template<class T> inline T SQR(T x) {return (x*x);}
template<class T> T GCD(T a,T b) {return ((!b)?(a):GCD(b,a%b));}
template<class T> T fastPow(T Base,T Power) {T Result=1; while(Power>0){if(Power&((T)1))Result*=Base; Power>>=1; Base*=Base;} return Result;}
template<class T> T fastModPow(T Base,T Power,T Mod) {T Result=1; while(Power>0){if(Power&((T)1))Result=(Result*Base)%Mod; Power>>=1; Base=(Base*Base)%Mod;} return (Result%Mod);}
inline int compDouble(double x,double y) {double d=x-y; if(d-ERR>0.0) return 1; else if(d+ERR<0.0) return -1; else return 0;}

#define all(X)       (X).begin(),(X).end()
#define Size(X)      ((int)(X).size())
#define DUMP(x)      cout << #x << " = " << x << endl;
#define rep(x,n)     for(x=0;x<(int)(n);x++)
#define fori(x,a,b)  for(x=(a);x<=(b);x++)
#define ford(x,a,b)  for(x=(a);x>=(b);x--)
#define Mem(X,with)  memset((X),(with),sizeof(X))
#define Each(X,itr)  for( __typeof((X).begin()) itr=(X).begin(); itr!=(X).end(); itr++)
#define Contains(X,item)    ((X).find(item)!=(X).end())
#define Contains_n(X,item)	(find((X).begin(),(X).end(),(item))!=(X).end())
#define PB  push_back
#define MP  make_pair
#define fs  first
#define sc  second

typedef unsigned long long ULL;
typedef long long      LL;
typedef stringstream   SS;
typedef vector<string> VS;
typedef vector<double> VD;
typedef vector<LL>     VL;
typedef vector<int>    VI;
typedef pair<int,int>  Pii;

int main()
{
	int _kase = 1;
	#ifdef ONLINE_JUDGE
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	#else
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	_kase = 22;
	#endif

	int i,j,k,n,m;

	while(_kase--)
	{
		cin>>n>>m;
		if(min(m,n)==2 && max(m,n)==2)
		{
			cout<<4<<endl;
			continue;
		}
		if(min(m,n)==2 && (max(m,n)==2 || max(m,n)==3))
		{
			cout<<4<<endl;
			continue;
		}
		i=((n+2)/3)*m;
		j=((m+2)/3)*n;
		cout<<max(i,j)<<endl;
	}

	return 0;
}

#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

int a[2000][2000], n, m, k = 0;

int f(int n) {
    if(n % 3 == 0) return n / 3;
    else return n / 3 + 1;
}

int main () {

    cin >> n >> m;

    if(n == 1 || m == 1 || (n == 2 && m == 2)) {
        cout << n * m;
        return 0;
    }

    if(n < m) swap(n, m);
    if(m == 2) {
        if(n > 3) cout << n;
        else cout << 4;
        return 0;
    }

    int ans = max(m * f(n), n * f(m));

    cout << ans;

    return 0;
}

#define _CRT_SECURE_NO_DEPRECATE

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <limits.h>
#include <list>
#include <map>
#include <set>
#include <string>
#include <time.h>
#include <vector>

#define nextLine() {for(int c=getchar(); c!='\n' && c!=EOF; c=getchar());}
#define sqr(a) ((a)*(a))
#define has(mask,i) (((mask) & (1<<(i))) == 0 ? false : true)
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

#define TASK "file"

using namespace std;

#define pii pair<int,int>
#define mp(x, y) make_pair(x, y)
#define pb(_o_) push_back(_o_)

typedef long long LL;
typedef unsigned long long ULL;
typedef long double ldb;

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<int> vb;
typedef vector<vi> vvb;
typedef list<int> li;
typedef multiset<int>::iterator siit;

const int inf = (1 << 30) - 1;
const ldb eps = 1e-9;
const ldb pi = fabs(atan2(0.0, -1.0));

int *ass;
void ML()
{
    for (;;)
    {
        ass = new int[2500000];
        for (int i = 0; i < 2500000; i++)
            ass[i] = rand();
    }
}

int n, m;

void LoAd()
{
    cin >> n >> m;
    if (1 == n)
    {
        cout << m;
        exit(0);
    }
    if (1 == m)
    {
        cout << n;
        exit(0);
    }
    if (n % 2 == 1 && m % 2 == 1)
    {
        cout << (n * m + 1) / 2;
        exit(0);
    }
    cout << n * m / 2;
    exit(0);
}

vvi desk;

int dx[] = {1,  1, 2,  2, -1, -1, -2, -2};
int dy[] = {2, -2, 1, -1,  2, -2,  1, -1};

int fuck = 88666;
int shit = 0;

bool good(const int x, const int y)
{
    if (x < 0 || x >= m || y < 0 || y >= n)
        return false;
    if (1 == desk[y][x])
        return false;
    return true;
}

bool isclear(const int x, const int y)
{
    if (x < 0 || x >= m || y < 0 || y >= n)
        return true;
    if (1 == desk[y][x])
        return false;
    return true;
}

bool put(const int x, const int y)
{
    if (!good(x, y))
        return false;
    for (int i = 0; i < 8; i++)
    {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (!isclear(nx, ny))
            return false;
    }
    return true;
}
int res = 0;
int maxres = 0;

vvi dmax;

void fusrohda()
{
    int cm1 = n * ( (m + 2) / 3);
    int cm2 = m * ( (n + 2) / 3);
    int cm = max(cm1, cm2);
    cout << maxres << endl;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
            printf("%d", dmax[i][j]);
        puts("");
    }
    exit(0);
}

void dfs(const int x, const int y)
{

    shit++;/*
    if (shit > fuck)
    {
        fusrohda();
    }
    */

    if (y >= n)
    {
        // check
        if (maxres < res)
        {
            maxres = res;
            dmax = desk;
        }
        return;
    }
    if (put(x, y))
    {
        // ставим
        desk[y][x] = 1;
        res++;
        if (x == m - 1)
            dfs(0, y + 1);
        else
            dfs(x + 1, y);
        desk[y][x] = 0;
        res--;
    }
    // не ставим
    if (x == m - 1)
        dfs(0, y + 1);
    else
        dfs(x + 1, y);

}

void SoLvE()
{
    desk.resize(n, vi(m, 0));
    dfs(0, 0);
    fusrohda();
}

int main()
{
    srand( (int) time(NULL));
    //freopen(TASK".in","r",stdin); freopen(TASK".out","w",stdout);
    LoAd();
    SoLvE();
    return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<double,double> pdd;

int main() {
	cin.sync_with_stdio(); cin.tie(0);
	int n, m;
	cin >> n >> m;
	if (m > n) swap(n,m);
	if (n <= 2 && m <= 2)
		cout << n*m << endl;
	else if (m == 2) {
		cout << 4*(n/4) + 2*min(n%4, 2) << endl;
	}
	else
		cout << (n*m+1)/2 << endl;
}

#include <iostream>

using namespace std;

int work(int a, int b)
{
    if (a == 1 || b == 1)
        return a * b;
    if (a == 2 && b == 2)
        return a * b;
    if ((a == 2 && b == 3) || (a == 3 && b == 2))
        return 4;
    return (a * b)/ 2 + 1;
}

int main()
{
    int a, b;

    cin >> a >> b;

    cout << work(a, b) << endl;

    return 0;
}

#include <bits/stdc++.h>
#include <functional> // for less
#include <iostream>
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(ar) ar.begin(), ar.end()
#define mp make_pair
#define sot(bello) bello.begin(),bello.end()
#define bitc  __builtin_popcountl
#define fr(i,a,b) for (int i = (a), _b = (b); i <= _b; i++)
#define frr(i,a,b) for (int i = (a), _b = (b); i >= _b; i--)
#define rep(i,n) for (int i = 0, _n = (n); i < _n; i++)
#define repr(i,n) for (int i = n - 1; i >= 0; i--)
#define fill(ar,val) rep(i,sizeof(ar)/sizeof(ll)) ar[i]=val
#define fill0(ar) fill((ar), 0)
#define foreach(it,ar) for ( typeof(ar.begin()) it = ar.begin(); it != ar.end(); it++ )
#define fillinf(ar, n) fr(i,0,(n)) ar[i] = INF
#define MAXN   100010
#define MOD 1000000007
#define debug(x) cout<<#x<<": "<<x<<endl
#define arr1d(a,n) cout << #a << " : "; fr(_,1,n) cout << a[_] << ' '; cout << endl;
#define arr1d0(a,n) cout << #a << " : "; rep(_,n) cout << a[_] << ' '; cout << endl;
#define arr2d(a,n,m) cout << #a << " :" << endl; fr(_,1,n) {fr(__,1,m) cout << a[_][__] << ' '; cout << endl;}
#define arr2d0(a,n,m) cout << #a << " :" << endl; rep(_,n) {rep(__,m) cout << a[_][__] << ' '; cout << endl;}
#define dbug(x) cout<<#x<<": "<<x<<" "
auto clk=clock();
#define PI 3.1415926535897932385
#define fi first
#define se second
#define arr1d(a,n) cout << #a << " : "; fr(_,1,n) cout << a[_] << ' '; cout << endl;
#define arr1d0(a,n) cout << #a << " : "; rep(_,n) cout << a[_] << ' '; cout << endl;
#define arr2d(a,n,m) cout << #a << " :" << endl; fr(_,1,n) {fr(__,1,m) cout << a[_][__] << ' '; cout << endl;}
#define arr2d0(a,n,m) cout << #a << " :" << endl; rep(_,n) {rep(__,m) cout << a[_][__] << ' '; cout << endl;}

# define INF LLONG_MAX
const int dx[]={0,0,-1,1},dy[]={-1,1,0,0};
const int dx8[]={-1,-1,-1,0,1,1,1,0}, dy8[]={-1,0,1,1,1,0,-1,-1};
/* This Template is authored by Ankit Anvesh */

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// gcd for negatives too
/* ll gcd(ll a, ll b) {
 if (a == 0) return b;
 if (b == 0) return a;
 if (b < 0) return gcd(a, -1 * b);
 if (a < 0) return gcd(-1 * a, b);
 if (a > b) return gcd(b, a);
 return gcd(b%a, a);
}
 */

//gcd
ll Gcd(ll a,ll b){
	if(a%b==0) return b;
	return Gcd(b,a%b);
}
//max
ll Max(ll a,ll b){
	if(a>b)
	return a;
	return b;
}
//min
ll Min(ll a,ll b){
	if(a<b)
	return a;
	return b;
}

void printvector(std::vector<ll> v){  for (int i = 0; i < v.size(); ++i){cout<<v[i]<<" ";}cout<<""<<endl;}
void printarray(ll a[],ll n){for (ll i = 0; i < n; ++i){cout<<a[i]<<" ";}cout<<""<<endl;}

ll findlcm(vector<ll> arr, ll n)
{
    // Initialize result
    ll ans = arr[0];

    // ans contains LCM of arr[0], ..arr[i]
    // after i'th iteration,
    for (int i = 1; i < n; i++)
        ans = (((arr[i] * ans)) /
                (Gcd(arr[i], ans)));

    return ans;
}

 ll power(ll x, ll y, ll p)
{
    ll res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res*x) % p;

        y = y>>1;
        x = (x*x) % p;
    }
    return res;
}

ll lowerbound(ll k,vector<ll> v){
  //lowerbound to be used when first index such that
  // ar[index]>=k is needed

  ll l=0;
  ll size=v.size();
  ll r=size-1;
  ll mid;
  while (l<=r)
  {
      mid=(l+r)/2;
      if(v[mid]<k) l=mid+1;
      else{
          r=mid-1;
      }
  }
  return l;

}

ll upperbound(ll k,vector<ll> v){
  //lowerbound to be used when first index such that
  // ar[index]>k is needed
  ll l=0;
  ll size=v.size();
  ll r=size-1;
  ll mid;
  while (l<=r)
  {
      mid=(l+r)/2;
      if(v[mid]>k) r=mid-1;
      else{
          l=mid+1;
      }
  }
  return l;

}

ll spf[MAXN];

void sieve()
{
    spf[1] = 1;
    for (int i=2; i<MAXN; i++)
      spf[i] = i;
   for (int i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (int i=3; i*i<MAXN; i++)
    {
        if (spf[i] == i)
        {
           for (int j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }
}

//Segment Tree Implementation

          //const ll N = 100000;

ll n, m;

// BIT tree
/*ll BIT[100010];
start indexing from 1
void update(ll x,ll val){

  for (; x <=n ; x +=(x&(-x)) )
     BIT[x]+=val;

}
ll query(ll x){
  ll sum=0;
  for(;x>0;x -= (x&(-x)) )
    sum+=BIT[x];
  return sum;

}*/

//Dijkstra's Algorithm
// if x->y (weight=w) then v[x].push_back(mp(y,w));

vector<ll> shortPath( vector<pair<ll,ll> > v[],ll src,ll V=0)
{
     set< pair<ll,ll> > setds;

    ll sizee=V;
    ll IN=INF;
    vector<ll> dist(sizee, IN);
    vector<bool> vis(sizee,false);
    setds.insert(make_pair(0, src));
    dist[src] = 0;

    while (!setds.empty())
    {
        pair<ll, ll> tmp = *(setds.begin());
        setds.erase(setds.begin());

        ll u = tmp.second;
        if(vis[u]) continue;
        vis[u]=true;
        vector< pair<ll, ll> >::iterator i;
        for (auto i = v[u].begin(); i != v[u].end(); ++i)
        {
            ll v = (*i).first;
            ll weight = (*i).second;
      if (dist[v] > dist[u] + weight)
            {
                if (dist[v] != INF)
                    setds.erase(setds.find(make_pair(dist[v], v)));

                dist[v] = dist[u] + weight;
                setds.insert(make_pair(dist[v], v));
            }
        }
    }
    return dist;
}

ll root(ll a[],ll r)
{
     if(a[r]==r)
     {
       return r;
     }
     else
     {
       ll x=root(a,a[r]);
       a[r]=x;
       return x;
     }

}

void unio(ll a[],ll  size[],ll  x,ll  y){
  x=root(a,x);
  y=root(a,y);
  if(x==y){return;}
  if(size[x]>=size[y])
  {
       a[y]=x;
       size[x]+=size[y];
  }
  else
  {
      a[x]=y;
      size[y]+=size[x];
  }

}

// Sieve Implementation
/*
for (ll i=2;i<=100005;i++)
        if (p[i]==0)
        for (ll j=2*i;j<=100005;j+=i) p[j]=1; */

// Dfs search

//do not use n , m , N , C

// Using iterators in C++
//set<ll>:: iterator it;
// string to integer stuuu()
// string to long long stoll()
// string to float stof
// string.substr(position,length);
// integer to string to_string();
// intialize 2d vector vector<vector<ll>> dp(105,vector<ll>(105));

int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
ll txt=1;
//cin>>txt;
while(txt--)
{
   cin>>n;
   cin>>m;
   ll op1,op2;
   op1=op2=0;
   ll mx=max(n,m);
   ll mi=min(n,m);
   if(mx<=3){
       if(mi==1){
           cout<<mx*mi<<endl;
            //return 0;
       }
       else if(mx==2 && mi==2){
           cout<<4<<endl;
       }
       else if(mx==3 && mi==2){
            cout<<4<<endl;
       }
       else
       {
           cout<<5<<endl;
       }

    return 0;
   }

   ll mat[n][m];
   rep(i,n){
       rep(j,m){
           mat[i][j]=0;
       }
   }
    op1=0;
   for(ll i=0;i<n;i++){
       ll j;
       if(i%2==0)
       j=0;
       else
        j=1;
       for(;j<m;j+=2){
           mat[i][j]=1;
         op1++;
       }
   }
   /* rep(i,n){
       rep(j,m){
          cout<<mat[i][j]<<" ";
       }
       cout<<endl;
   } */

   cout<<op1<<endl;

}
//return 0;
}

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

signed main() {
    int n,m;
    cin>>n>>m;
    if(n>m){
        swap(n,m);
    }
    if(n==1){
        cout<<m<<endl;
    }
    if(n==2){
        cout<<2*(2*(n/4)+ min(2,n%3))<<endl;
    }
    else{
        cout<<(n*m+1)/2<<endl;
    }
  return 0;

}

#include<iostream>
#include<stdio.h>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<fstream>
using namespace std;
typedef long long int ll;
int xx[]={1,1,1,0,-1,-1,-1,0};
int yy[]={-1,0,1,1,1,0,-1,-1};
ll gcd(ll a,ll b)
{ return ((a%b==0)?b:gcd(b,a%b)) ;}

int main()
{
    //freopen("input.txt","r",stdin);
    // freopen("output.txt","w",stdout);
     int n,m,k;
     cin>>n>>m;
     if(n>m)
        swap(n,m);
     if(n==1)
        cout<<m<<endl;

     if(n==2)
     {
         k = m%4;
        if(k==2)
            k = 3;
         cout<<(m/4)*4 + k*2<<endl;;
         return 0;
     }

     cout<<(n*m+1)/2<<endl;

 return 0;
}

//
//  Created by Henry Cafaro
//  Copyright © 2020 Henry Cafaro. All rights reserved.
//

# include <iostream>
# include <string>
# include <vector>
# include <algorithm>
# include <bitset>
# include <queue>
# include <cstring>

#define ll long long

using namespace std;

int n,m;

int round(int q){
    if(q%2 == 0) return q/2;

    return (q+1)/2;

}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n >> m;

    cout << round(n*m) << endl;

}

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main(){
    int n,m;
    while(cin>>n>>m){
        int ans=n*m;
        ans+=(n*m%2);
        cout<<ans/2<<endl;

    }

    return 0;
}

#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <cctype>
#include <fstream>

using namespace std;

int  main()
{
	int n, m, k;
	cin >> n >> m;
	k = n * m;
	if (n == 1 || m == 1)
	{
		cout << n*m;
		return 0;
	}
	k /=2;
	if ( n % 2 != 0 || m % 2  != 0)
		k++;

	cout << k;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define max1 200005
#define siz 100000
#define mod 1000000007
#define inf 1e18*4
#define ll long long int
#define debug(x) cout<<#x<<" "<<x<<endl
#define jam(x) cout<<"Case #"<<x<<": "
ll tt;
#define run_time cout << "\nTIME = " << clock() - tt << endl; tt = clock();
typedef pair<ll,ll> pr;
int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  #ifndef ONLINE_JUDGE
  freopen("input.txt","r",stdin);
  freopen("output.txt","w",stdout);
  tt = clock();
  #endif
  ll n,m;
  cin>>n>>m;
  if(n==1)
  {
    cout<<m<<endl;
    return 0;
  }
  if(m==1)
  {
    cout<<n<<endl;
    return 0;
  }
  ll ans=0,ans1=0;
  if(m%2==0)
  {
    ans=(m/2)*n;
  }
  else
  {
    ll x,y;
    if(n%2==0)
    {
      x=y=n/2;
    }
    else
    {
      x=(n/2)+1;
      y=n/2;
    }
    ans=(x*((m/2)+1))+(y*(m/2));
  }
  if(n%2==0)
  {
    ans1=(n/2)*m;
  }
  else
  {
    ll x,y;
    if(m%2==0)
    {
      x=y=m/2;
    }
    else
    {
      x=(m/2)+1;
      y=m/2;
    }
    ans1=(x*((n/2)+1))+(y*(n/2));
  }
  cout<<max(ans,ans1)<<endl;
  return 0;
}

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <string>
#include <cstring>
#include <cmath>
#include <fstream>
#include <ctime>
#include <queue>

using namespace std;

int n,m;
int ans1, ans2;

int main()
{
    cin>>n>>m;
    if ( n%4 == 0)
     ans1 = (n/4+1)*m;
     else ans1 = n/4*m;
    if ( m%4 == 0)
     ans2 = (m/4+1)*n;
     else ans2=(m/4)*n;
    cout<<max(ans1, ans2);
    return 0;
}

#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define nl cout<<'\n'
#define ff first
#define ss second
#define READ freopen("input.txt","r",stdin);
#define WRITE    freopen("output.txt","w",stdout);
#define fill(a,x) memset(a,x,sizeof(a));
#define loop(i,x,n) for(int i=x;i<n;i++)
#define TC() ll ttwea;cin>>ttwea;while(ttwea--)
#define ll long long
#define mod 1000000007
//#define N 100020
#define vi vector<ll>
#define pb push_back
#define mp make_pair
//#define sort(x) sort(x.begin(),x.end())
//#define reverse(x) reverse(x.begin(),x.end())
#define all(a)      a.begin(), a.end()
#define ull unsigned long long
#define inf 1000000000000
#define debug1(x) cerr << #x << ": " << x <<'\n'
#define debug2(x, y) cerr << #x << ": " << x << '\t' << #y << ": " << y <<'\n'
#define debug3(x, y, z) cerr << #x << ": " << x << '\t' << #y << ": " << y << '\t' << #z << ": " << z <<'\n'
using namespace std;
//ll dx[]={1,0,-1,0};ll dy[]={0,1,0,-1}; //4 Direction
//ll dx[]={1,1,0,-1,-1,-1,0,1};ll dy[]={0,1,1,1,0,-1,-1,-1};//8 direction
ll gcd(ll x,ll y)
{
    if(y==0)
        return x;
    else
        return gcd(y,x%y);
}
ll expo(ll n,ll m)   //MODULAR EXPONENTIATION
{
    ll r=1;
    while(m>0)
    {
        if(m%2)
            r=(r*n)%mod;
        n=(n*n)%mod;
        m=m/2;
    }
    return r%mod;
}
int main()
{

   IOS;
   #ifndef ONLINE_JUDGE
   freopen("input.txt","r",stdin);
   freopen("output.txt","w",stdout);
   #endif
   /********************* Code starts here ************************/
   ll n,m;
   cin>>n>>m;
   ll ans=n*(m/2);
   cout<<ans;
   return 0;
}

#include<iostream>
#include<algorithm>
#include<vector>

using namespace std;

int main()
{
    //freopen("input.txt","r",stdin);
    int n,m;
    scanf("%d %d",&n,&m);

    int maxi = 0;

    for(int i=0; i<n; i++)
    {
        if(i&1)
        {
            maxi += (m-1)/2 + 1;
        }
        else
        {
            maxi += m/2;
        }
    }

    int maxi_4 = 0;
    int k = (n==2 ? m : (m == 2 ? n : -1));
    for(int i=0; i<k; i+=4)
    {
        if(i+1<k)
            maxi_4 += 4;
        else
            maxi_4 += 2;
    }
    maxi = max(maxi, maxi_4);
    printf("%d",maxi);
    return 0;
}

//In the name of God
#include <iostream>
using namespace std;
int main(){
    int n,m;
    cin >> n >> m;
    cout << (n * m)/2 + (n * m)%2 << endl;
    return 0;
}

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int main()
{
    int n,m,a,b,ta,tb;
    cin>>n>>m;
    if(n==1)
    {
        cout<<m<<endl;
        return 0;
    }
    if(m==1)
    {
        cout<<n<<endl;
        return 0;
    }
    if(n==2 && m==2)
    {
        cout<<n*m<<endl;
        return 0;
    }
    int t=n*m;
    if(t&1)
        cout<<(t+1)/2<<endl;
    else
        cout<<t/2<<endl;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
int n,m,res,xam,visited[1005][1005];

void tambah(int row, int col){
	int dx[8] = {-2,-1,1,2,2,1,-1,-2};
	int dy[8] = {1,2,2,1,-1,-2,-2,-1};
	for(int i = 0; i < 8; i++){
		int targetrow = row+dx[i];
		int targetcol = col+dy[i];
		if(targetrow>=0&&targetrow<n&&targetcol>=0&&targetcol<m){
			visited[targetrow][targetcol] = 1;
		}
	}
}

int main(){
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		for(int j = i%2; j < m; j+=2){
			if(!visited[i][j]){
				visited[i][j] = true;
				res++;
				tambah(i,j);
			}
		}
	}
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			if(!visited[i][j]){
				visited[i][j] = true;
				res++;
				tambah(i,j);
			}
		}
	}
	xam = res;
	res = 0;
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			visited[i][j] = 0;
		}
	}
	for(int i = 0; i < n; i++){
		for(int j = !(i%2); j < m; j+=2){
			if(!visited[i][j]){
				visited[i][j] = true;
				res++;
				tambah(i,j);
			}
		}
	}
	for(int i = 0; i < n; i++){
		for(int j = 0; j < m; j++){
			if(!visited[i][j]){
				visited[i][j] = true;
				res++;
				tambah(i,j);
			}
		}
	}
	xam = max(xam,res);
	if(n==2&&m>=5&&((m%4) > 0))xam = max(xam,m+1);
	else if(m==2&&n>=5&&((n%4) > 0))xam = max(xam,n+1);
	printf("%d\n", xam);
}

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
	int n,m;
	cin>>n>>m;
	int a=(n/3),b=m/3;
	if(n%3!=0)a++;
	if(m%3!=0)b++;
	cout<<max(a*m,b*n)<<endl;

	return 0;
}

#include<iostream>
using namespace std;

int main()
{
	int n, m;
	cout << n << m;
	cout << (n*m + 1) / 2 << endl;
}

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <unordered_set>
#include <queue>
using namespace std;

int main() {
    int a, b;
    cin >> a >> b;
    int tm1 = a;
    int tm2 = b;
    if (b < a) swap(a, b);
    if (a == 1) {
          cout << b;
          return 0;
    }
    int ans = 0;
    while(a > 0) {
            ans += (a / 2) + (a & 1) + (b / 2) + (b & 1);
            a--;
            b--;
    }

    cout << ans - 1;

    return 0;
}

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

#define SZ(x) ((int)x.size())

vector < vector<pair<int,int> > > adj;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, m; cin >> n >> m;
    if(n > m) swap(n, m);

    vector <int> vec;

    if(n == 1) {
        cout << m << endl;
        return 0;
    } else if(n == 2) {
        if(m == 2) {
            cout << 4 << endl;
            return 0;
        }
        else if(m == 3) {
            cout << m+1 << endl;
            return 0;
        } else {
            vec.push_back(m);
            vec.push_back((m/4) * 4 + min(2, (m % 4)) * 2);
        }
    } else if(n == 3) {
        if(m == 3) {
            cout << 4 << endl;
            return 0;
        } else if((m-1) % 3) {
            vec.push_back(5 + ((m-1) / 3) * 3);
        }
    }

    vec.push_back((1 + (n - 1) / 3) * m);
    vec.push_back((1 + (m - 1) / 3) * n);
    vec.push_back((((n+1) / 2) * ((m+1) / 2)) + ((n / 2) * (m / 2)));

    cout << *max_element(vec.begin(), vec.end()) << endl;

    return 0;
}

// You just can't Sugar Coat Shit !!!
#include <bits/stdc++.h>
#define ll long long int
#define f(i,n) for(ll i=0;i<n;i++)
#define rf(i,n) for(ll i=n;i>=0;i--)
#define endl '\n'
#define pub push_back
#define vf v[i].first
#define vs v[i].second
#define mp make_pair
#define z 1000000007
#define every(it,x) for(auto it:x)
using namespace std;
ll powMod(ll x,ll y){ll p=1; while(y){if(y%2){p=(p*x)%z;} y/=2; x=(x*x)%z;} return p;}
ll invMod(ll x){return powMod(x,z-2);}
ll gcd(ll a, ll b) {return b == 0 ? a : gcd(b, a % b);}

void solve(){
   ll n,m;
   cin>>n>>m;
   ll x = n*m;
   if(n==1 || m==1){
       cout<<x<<endl;
   }
   else if(x%2){
       cout<<x/2+1<<endl;
   }
   else cout<<x/2<<endl;
}
int main(){
    ios_base::sync_with_stdio(0) ;
    cin.tie(0) ; cout.tie(0) ;

    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #else

    #endif
    solve();
    #ifndef ONLINE_JUDGE
        cout<<"\nTime Elapsed: "<<1.0*clock()/ CLOCKS_PER_SEC<<" Sec\n";
    #endif
    return 0;
}

#include <cstdio>
#include <numeric>
#include <iostream>
#include <vector>
#include <set>
#include <cstring>
#include <string>
#include <map>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <bitset>
#include <queue>
#include <sstream>
#include <deque>

using namespace std;

#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i = 0; i < (n); i++)
#define re return
#define fi first
#define se second
#define sz(x) ((int) (x).size())
#define all(x) (x).begin(), (x).end()
#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(abs(x))
#define y0 y3487465
#define y1 y8687969
#define fill(x,y) memset(x,y,sizeof(x))

typedef vector<int> vi;
typedef long long ll;
typedef long double ld;
typedef double D;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<string> vs;
typedef vector<vi> vvi;

template<class T> T abs(T x) { re x > 0 ? x : -x; }

int n;
int m;

int main () {
    scanf ("%d%d", &n, &m);
    if (n > m) swap (n, m);
    if (n == 1) printf ("%d\n", m); else
    if (n == 2) printf ("%d\n", m + m % 2); else printf ("%d\n", (n * m + 1) / 2);
    return 0;
}

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

using namespace std;

#define REP(i,k,n) for(int i=k;i<n;i++)
#define REV(i,k,n) for(int i=k;i>=n;i--)
#define SZ(x) ((int)x.size())
#define CLR(v,c) memset(v,c,sizeof (v))
#define eps 1e-10
#define mp make_pair

typedef  long long ll ;
typedef  long double ld ;

const int NN = 1000 * 1000 + 100 ;

int main () {
#ifdef HOMEPC
	freopen ("in.in","r",stdin) ;
#endif
	ios::sync_with_stdio (false);

	int m,n ;
	cin >> m >> n ;

	int B = 0 , W = 0 ;
	//if (m == 1 || n == 1 || m * n <= 1000) {
		REP (i,0,m) REP (j,0,n) {
			bool f = true ;
			REP (x,-5,5 + 1) REP (y,-5,5 + 1) if (x * x + y * y == 5) {
				if (x + i >= 0 && x + i < m && y + j >= 0 && y + j < n) { f = false ; break ; }
			}
			if (f) {
				if ((i + j) % 2 == 0) W ++ ;
				else B ++ ;
			}
		}
	//}
	int nB = (m * n) >> 1 ;
	int nW = m * n - nB ;
	cout << max (W + nB,B + nW) << endl ;

}

#define MN(a,b)a<b?a:b
#include <iostream>
using namespace std;
int main(){
    int a, b;

    cin >> a >> b;
    if (a == 1){ cout << b; return 0; }
    if (b == 1){ cout << a; return 0; }
    //if (b == 2){ cout << 2 * (2 * (a / 2) + MN(a % 4, 2)); return 0; }
    if (b == 2){ cout << a + 1; return 0; }
    cout << a*b - (a*b) / 2;
}

#include<bits/stdc++.h>

using namespace std;

#define ll long long
const int N = 201;

int main(void)
{

  int n,m; cin>>n>>m;

  int ans = 0;

  for(int i=1; i+2<=m; i+=2)
  {
    ans += n;
  }
  if(m%2 == 1)
    ans += ceil(double(n)/double(2));
  ans = max(ans,n);
  ans = max(ans,m);
  cout<<ans<<endl;

  return 0;
}

//wrong answer

#include <iostream>

using namespace std;
int main()
{
    int n,m;
    cin>>n>>m;
    if(n==1)cout<<m<<endl;
    else {
        if(m==1)cout<<n<<endl;
        else {
            if(n==2){
                if(m==2 || m==3)cout<<"4"<<endl;
                else cout<<(n*m)/2<<endl;
            }
            else {
                if(m==2){
                    if(n==2 || n==3)cout<<"4"<<endl;
                    else cout<<(n*m)/2<<endl;
                }
                else{
                    if((n*m)%2==1)cout<<((n*m)/2)+1<<endl;
                    else cout<<(n*m)/2<<endl;
                }
            }
        }
    }

}

#include <iostream>
using namespace std;
int main ()
{int n,m,l;
cin>>n>>m; l=n*m/2;
if (n==2 || m==2) cout<<((l-l%4+4)/2-(int)(l%4==1))*2<<endl;
else cout<<n*m/2+n*m%2;

return 0;
}

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
ll n,m;
bool b[2002][2002];
void mark(ll x,ll y)
{
        if(y + 1 <= m && x - 2 >= 1)
        {
                b[x - 2][y + 1] = false;
        }
        if(y + 1 <= m && x + 2 <= n)
        {
                b[x + 2][y + 1] = false;
        }
        if(y + 2 <= m && x - 1 >= 1)
        {
                b[x-1][y+2] = false;
        }
        if(y + 2 <= m && x + 1 <= n)
        {
                b[x+1][y+2] = false;
        }
}
ll solve1()
{
        memset(b , true,sizeof b);
        ll k = m/3;
        if(m%3 == 1)
        {
                return (n*(k + 1));
        }
        ll ret = ((m - 1)/3) + 1;
        ret = ret*n;
        k = (m-1)/3;
        ll col = 3*k + 1;
        while(col <= m)
        {
                for(ll i=1;i<=n;i++)
                {
                        if(b[i][col])
                        {
                                mark(i , col);
                                if(col != (3*k + 1)) ret++;
                        }
                }
                col++;
        }
        return ret;
}
int main()
{
        //memset(b,true,sizeof b);
        cin >> n >> m;
        if(n == 1 || m == 1){
                cout << n*m << endl; return 0;
        }
        if(n == 2)
        {
                ll ans = 0;
                ll k = m/4;
                if(m%4 == 0)
                {
                        ans = 4*k;
                }else if(m%4 == 1)
                {
                        ans = 4*k + 2;
                }else if(m%4 == 2 || m %4 == 3)
                {
                        ans = 4*(k + 1);
                }
                cout << max(ans , m) << endl; return 0;
        }
        if(m == 2)
        {
                swap(m,n);
                ll ans = 0;
                ll k = m/4;
                if(m%4 == 0)
                {
                        ans = 4*k;
                }else if(m%4 == 1)
                {
                        ans = 4*k + 2;
                }else if(m%4 == 2 || m%4 == 3)
                {
                        ans = 4*(k + 1);
                }
                cout << max(ans , m) << endl; return 0;
        }
        ll ans1 = solve1();
        swap(n,m);
        ll ans2 = solve1();
        cout << max(ans1 , ans2) << endl;
        return 0;
}

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

int main()
{
    double n, m; int x1, x2;
    cin>>n>>m; x1=ceil(n/2); x2=ceil(m/2);
    if(n==1) cout<<m;
    else if(m==1) cout<<n;
    else cout<<((x1*x2)+((n-x1)*(m-x2)));
    return 0;
}

#include<bits/stdc++.h>
#define rep(i,n) for( int (i)=0;(i)<(int)(n);(i)++)
#define sz(v) (int)((v).size())
#define FOR(i,k,n) for(int i=(k);i<(int)(n);i++)
#define VI vector<int>
#define VS vector <string>
#define SORT(c) sort((c).begin(),(c).end())
#define pb push_back
#define gc getchar_unlocked
#define Q queue<int>
#define s(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define p(n) printf("%d",n)
#define pll(n) printf("%lld",n)
#define mem(s,v) memset(s,v,sizeof s)
#define pp pair<int,int>
#define pp1 pair<int,pair<int,int> >
#define INF 999999
#define VP vector<pp>
#define QP queue<pp>
typedef long long ll;
using namespace std;

int main()
{
        #ifndef ONLINE_JUDGE
        freopen("in.txt", "r", stdin);
        #endif
        int n,m;
        s(n);s(m);
        int c=0;

        for(int i=1;i<=n;i++)
        {
                int j;
                if(i%2!=0)
                    j=1;
                else
                    j=2;
                for(;j<=m;j+=2)
                        c++;
        }
        if(n==1)
                cout<<m<<endl;
        else if(m==1)
                cout<<n<<endl;
        else if(n==2)
        {
                if(m%2!=0)
                        cout<<m+1<<endl;
        }
        else if(m==2)
        {
                if(n%2!=0)
                        cout<<n+1<<endl;
        }
        else
            cout<<c<<endl;

    }