#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <string>
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
#include <cmath>

using namespace std;

void SolveA()
{
	int a, b;
	scanf("%d %d", &a, &b);

	int x = ceil((a + b) / 2.0);
	printf("%d\n", x);
}

void AtCoderSolveA()
{
	// 値の読み込み
	int a, b;
	scanf("%d %d", &a, &b);

	// 結果の出力
	// a = 1, b = 3(1 + 3 = 4 / 2 = 2)の時 -> 1 + 3 + 1 = 5 / 2 = 2.5で，int型によって，2に切り捨てられる 
	// a = 3, b = 3(3 + 3 = 6 / 2 = 3)の時 -> 3 + 3 + 1 = 7 / 2 = 3.5で，int型によって，3に切り捨てられる
	// a = 7, b = 4(7 + 4 = 11 / 2 = 5.5)の時 -> 7 + 4 + 1 = 12 / 2 = 6となる．
	// このように，int型で+1することで，切り上げを行うことが出来る．
	printf("%d\n", (a + b + 1) / 2);
}

void SolveB()
{
	string s, t;
	cin >> s;	// s
	cin >> t;	// t

	sort(s.begin(), s.end());	// sの中身を昇順ソート
	sort(t.rbegin(), t.rend());	// tの中身を降順ソート

	if (s < t)
	{
		printf("Yes\n");
	}
	else
	{
		printf("No\n");
	}
}

void SolveC()
{
	int N;
	scanf("%d", &N);

	vector<int> kind;
	//kind.resize(N);
	vector<int> numKind;
	numKind.resize(N, 0);

	int pos = 0;
	for (int i = 0; i < N; i++)
	{
		long long int a;
		cin >> a;
		if (std::find(kind.begin(), kind.end(), a) != kind.end())
		{
			// 見つかった
			int j = 0;
			while (kind[j] != a)
			{
				j++;
			}
			numKind[j]++;
		}
		else
		{
			numKind[pos]++;
			//kind[pos] = a;
			kind.push_back(a);
			pos++;
		}
	}

	long long int cnt = 0;
	for (int i = 0; i < pos; i++)
	{
		if (numKind[i] - kind[i] > 0)
		{
			cnt += (numKind[i] - kind[i]);
		}
		else if (numKind[i] - kind[i] < 0)
		{
			cnt += numKind[i];
		}
	}

	cout << cnt << "\n";
}

string sRoute;
string ansRoute;
int oriX, oriY;
int ansX, ansY;

string SearchRobotRoute(int *x, int *y, string s, int head)
{
	if (s.length() >= sRoute.length())
	{
		return s;
	}
	if (s == "")
	{
	}
	else if (std::equal(s.begin(), s.end(), sRoute.begin()))
	{
	}
	else
	{
		return s;
	}

	string s0;
	int x0 = *x + 1, y0 = *y;
	string s1;
	int x1 = *x, y1 = *y + 1;
	string s2;
	int x2 = *x - 1, y2 = *y;
	string s3;
	int x3 = *x, y3 = *y - 1;

	if (head == 0)
	{
		//s0 = s + SearchRobotRoute(&x0, &y0, s + "F", 0);
		//s1 = s + SearchRobotRoute(&x1, &y1, s + "TF", 1);
		//s2 = s + SearchRobotRoute(&x2, &y2, s + "TTF", 2);
		//s3 = s + SearchRobotRoute(&x3, &x3, s + "TF", 3);
		s0 = SearchRobotRoute(&x0, &y0, (s + "F").substr(), 0);
		s1 = SearchRobotRoute(&x1, &y1, (s + "TF").substr(), 1);
		s2 = SearchRobotRoute(&x2, &y2, (s + "TTF").substr(), 2);
		s3 = SearchRobotRoute(&x3, &y3, (s + "TF").substr(), 3);
	}
	else if (head == 1)
	{
		//s0 = s + SearchRobotRoute(&x0, &y0, s + "TF", 0);
		//s1 = s + SearchRobotRoute(&x1, &y1, s + "F", 1);
		//s2 = s + SearchRobotRoute(&x2, &y2, s + "TF", 2);
		//s3 = s + SearchRobotRoute(&x3, &x3, s + "TTF", 3);
		s0 = SearchRobotRoute(&x0, &y0, (s + "TF").substr(), 0);
		s1 = SearchRobotRoute(&x1, &y1, (s + "F").substr(), 1);
		s2 = SearchRobotRoute(&x2, &y2, (s + "TF").substr(), 2);
		s3 = SearchRobotRoute(&x3, &y3, (s + "TTF").substr(), 3);
	}
	else if (head == 2)
	{
		//s0 = s + SearchRobotRoute(&x0, &y0, s + "TTF", 0);
		//s1 = s + SearchRobotRoute(&x1, &y1, s + "TF", 1);
		//s2 = s + SearchRobotRoute(&x2, &y2, s + "F", 2);
		//s3 = s + SearchRobotRoute(&x3, &x3, s + "TF", 3);
		s0 = SearchRobotRoute(&x0, &y0, (s + "TTF").substr(), 0);
		s1 = SearchRobotRoute(&x1, &y1, (s + "TF").substr(), 1);
		s2 = SearchRobotRoute(&x2, &y2, (s + "F").substr(), 2);
		s3 = SearchRobotRoute(&x3, &y3, (s + "TF").substr(), 3);
	}
	else if (head == 3)
	{
		//s0 = s + SearchRobotRoute(&x0, &y0, s + "TF", 0);
		//s1 = s + SearchRobotRoute(&x1, &y1, s + "TTF", 1);
		//s2 = s + SearchRobotRoute(&x2, &y2, s + "TF", 2);
		//s3 = s + SearchRobotRoute(&x3, &x3, s + "F", 3);
		s0 = SearchRobotRoute(&x0, &y0, (s + "TF").substr(), 0);
		s1 = SearchRobotRoute(&x1, &y1, (s + "TTF").substr(), 1);
		s2 = SearchRobotRoute(&x2, &y2, (s + "TF").substr(), 2);
		s3 = SearchRobotRoute(&x3, &y3, (s + "F").substr(), 3);
	}

	if (x0 == oriX && y0 == oriY && s0 == sRoute)//std::equal(s0.begin(), s0.end(), sRoute.begin(), sRoute.end()))
	{
		ansX = x0;
		ansY = y0;
		ansRoute = s0;
		return s0;
	}
	else if (x1 == oriX && y1 == oriY && s1 == sRoute)//std::equal(s1.begin(), s1.end(), sRoute.begin(), sRoute.end()))
	{
		ansX = x1;
		ansY = y1;
		ansRoute = s1;
		return s1;
	}
	else if (x2 == oriX && y2 == oriY && s2 == sRoute)//std::equal(s2.begin(), s2.end(), sRoute.begin(), sRoute.end()))
	{
		ansX = x2;
		ansY = y2;
		ansRoute = s2;
		return s2;
	}
	else if (x3 == oriX && y3 == oriY && s3 == sRoute)//std::equal(s3.begin(), s3.end(), sRoute.begin(), sRoute.end()))
	{
		ansX = x3;
		ansY = y3;
		ansRoute = s3;
		return s3;
	}

	if (std::equal(s0.begin(), s0.end(), sRoute.begin(), sRoute.end()))
	{
		//*x = x0;
		//*y = y0;
		return s0;
	}
	else if (std::equal(s1.begin(), s1.end(), sRoute.begin(), sRoute.end()))
	{
		//*x = x1;
		//*y = y1;
		return s1;
	}
	else if (std::equal(s2.begin(), s2.end(), sRoute.begin(), sRoute.end()))
	{
		//*x = x2;
		//*y = y2;
		return s2;
	}
	else if (std::equal(s3.begin(), s3.end(), sRoute.begin(), sRoute.end()))
	{
		//*x = x3;
		//*y = y3;
		return s3;
	}
}

void SolveD()
{
	cin >> sRoute;
	scanf("%d %d", &oriX, &oriY);

	int rX = 0, rY = 0;

	string route = SearchRobotRoute(&rX, &rY, "", 0);
	
	// test
	cout << route << "\n";

	if (sRoute == ansRoute && oriX == ansX && oriY == ansY)
	{
		printf("Yes\n");
	}
	else
	{
		printf("No\n");
	}
	//if (sRoute == route && oriX == rX && oriY == rX)
	//{
	//	printf("Yes\n");
	//}
	//else
	//{
	//	printf("No\n");
	//}

	//cin >> sRoute;
	//int x, y;
	//scanf("%d %d", &x, &y);

	//int n = sRoute.length();
	//for (int i = 0; i < n; i++)
	//{
	//	
	//}
}

int main()
{
	//SolveA();
	//SolveB();
	//SolveC();
	//SolveD();

	AtCoderSolveA();
}

Measured memory_bytes: 256