#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

#define rep(i,a,n) for (int i=a;i<n;i++)

using namespace std;
int m;
string s;
int n;

int check(int maxc){
	int cnt = 0;
	int prev = -1;
	int cur = -1;
	for(int i=0;i<n;i++){
		if(s[i] < maxc+'a'){
			prev = i;
			cur = i;
		}
		if(s[i] == maxc+'a')
			cur = i;
		if(i-prev==m){
			if(cur>prev){
				cnt++;
				prev = cur;
			}else{
				return -1;
			}
		}
	}
	return cnt;
}

int main(){
	//freopen("input.txt","r",stdin);
	cin >> m;
	cin >> s;
	n = s.length();
	char maxc = 0;
	int cnt = 0;
	int iter = 0;
	vector<int> ans(26);
	for(int i=0;i<n;i++)
		ans[s[i]-'a']++;
	for(maxc=0;maxc<26;maxc++){
		int cnt = check(maxc);
		if(cnt!=-1){
			for(int i=0;i<maxc;i++)
				for(int j=0;j<ans[i];j++)
					cout << char(i+'a');
			for(int j=0;j<cnt;j++)
				cout << char(maxc+'a');
			cout << endl;
			return 0;
		}
	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
	int n = s.length();
	char maxc='a';
	int maxcnt = 0;
	int mxpos = 0;
	bool flag = true;
	int iter = 0;
	while(flag){
		char lmn=s[iter];
		int lpos = iter;
		for(int i=iter+1;i<min(n,iter+m);i++){
			if(s[i]<=lmn){
				lpos = i;
				lmn = s[i];
			}
		}
		if(lmn==maxc){
			maxcnt++;
		}else if(lmn>maxc){
			maxcnt = 1;
			maxc = lmn;
		}
//		cout << lmn << " " << lpos << endl;
		iter = lpos + 1;
		if(iter+m>=n)
			flag = false;
	}
	vector<char> ans(26);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = maxcnt;
	for(int i=0;i<26;i++)
		cout << string(ans[i],char(i+'a'));
	cout << endl;
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
	int n = s.length();
	char maxc='a';
	int maxcnt = 0;
	int mxpos = 0;
	int iter = 0;
	while(true){
		char lmn=s[iter];
		int lpos = iter;
		for(int i=iter+1;i<min(n,iter+m);i++){
			if(s[i]<=lmn){
				lpos = i;
				lmn = s[i];
			}
		}
		if(lmn==maxc){
			maxcnt++;
		}else if(lmn>maxc){
			maxcnt = 1;
			maxc = lmn;
		}
//		cout << lmn << " " << lpos << endl;
		iter = lpos + 1;
		if(iter+m>=n)
			break;
	}
	vector<char> ans(100);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = maxcnt;
	for(int i=0;i<ans.size();i++)
		cout << string(ans[i],char(i+'a'));
	cout << endl;
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

string gen_random(const int len) {
	static const char alphanum[] = "abcdefghijklmnopqrstuvwxyz";
	string ans;
	for (int i = 0; i < len; ++i) {
		ans += alphanum[rand() % (sizeof(alphanum) - 1)];
    	}
	return ans;
}

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
//	while(true){
//	s = gen_random(10+rand()%1000);
//	cout << s << endl;
	char maxc = 'a';
	int n = s.length();
	int cnt = 0;
	int iter = 0;
	for(maxc='a';maxc<='z';maxc++){
		int it = -1;
		cnt = 0;
		int prev = -1;
		int cur = -1;
		for(int i=0;i<n;i++){
			if(s[i] < maxc){
				prev = i;
				cur = i;
			}
			if(s[i] == maxc)
				cur = i;
			if(i-prev==m){
				if(cur>prev){
					cnt++;
					prev = cur;
				}else{
					cnt = -1;
					break;
				}
			}
		}
		if(cnt>0)
			break;
	}
//	cout << maxc << " " << cnt << endl;
	vector<char> ans(26);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = cnt;
	for(int i=0;i<ans.size();i++)
		cout << string(ans[i],char(i+'a'));
	cout << endl;
//	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

string gen_random(const int len) {
	static const char alphanum[] = "abcdefghijklmnopqrstuvwxyz";
	string ans;
	for (int i = 0; i < len; ++i) {
		ans += alphanum[rand() % (sizeof(alphanum) - 1)];
    	}
	return ans;
}

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
//	while(true){
//	s = gen_random(10+rand()%1000);
//	cout << s << endl;
	char maxc = 'a';
	int n = s.length();
	int cnt = 0;
	int iter = 0;
	for(maxc='a';maxc<='z';maxc++){
		int it = -1;
		cnt = 0;
		for(int i=0;i<n;i++){
			int out = it+m+1;
			for(int j=min(n,i+m)-1;j>=i;j--)
				if(s[j]<=maxc){
					if(s[j]==maxc)
						cnt++;
					out = j;
			//		cout << out << " " << i+m << endl;
					break;
				}
			if(out-it>m){
				break;
//				cout << out-it << endl;
			}
			it = out;
			i = it;
			if(it+m>=n)
				break;
		}

//		printf("%d %d %c\n",it,cnt, maxc);
		if(it+m>=n)
			break;
	}
//	cout << maxc << " " << cnt << endl;
	vector<char> ans(26);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = cnt;
	for(int i=0;i<ans.size();i++)
		cout << string(ans[i],char(i+'a'));
	cout << endl;
//	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

string gen_random(const int len) {
	static const char alphanum[] = "abcdefghijklmnopqrstuvwxyz";
	string ans;
	for (int i = 0; i < len; ++i) {
		ans += alphanum[rand() % (sizeof(alphanum) - 1)];
    	}
	return ans;
}

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
//	while(true){
//	s = gen_random(10+rand()%1000);
//	cout << s << endl;
	char maxc = 'a';
	int n = s.length();
	int cnt = 0;
	int iter = 0;
	for(maxc='a';maxc<='z';maxc++){
		int it = -1;
		cnt = 0;
		for(int i=0;i<n;i++){
			int out = it+m+1;
			int tst = -1;
			for(int j=min(n,i+m)-1;j>=i;j--){
				if(s[j]<=maxc){
					if(s[j]==maxc && tst==-1)
						tst = j;
					else{
						out = j;
						break;
					}
				}
			}
			if(tst<out && tst!=-1){
				out = tst;
			}
//			cout << out << endl;
			cnt+=(s[out]==maxc)?1:0;
			if(out-it>m){
				break;
//				cout << out-it << endl;
			}
			it = out;
			i = it;
			if(it+m>=n)
				break;
		}

//		printf("%d %d %c\n",it,cnt, maxc);
		if(it+m>=n)
			break;
	}
//	cout << maxc << " " << cnt << endl;
	vector<char> ans(26);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = cnt;
	for(int i=0;i<ans.size();i++)
		cout << string(ans[i],char(i+'a'));
	cout << endl;
//	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
	int n = s.length();
	char maxc = 0;
	int cnt = 0;
	int iter = 0;
	for(maxc=0;maxc<26;maxc++){
		cnt = 0;
		int prev = -1;
		int cur = -1;
		for(int i=0;i<n;i++){
			if(s[i] < maxc+'a'){
				prev = i;
				cur = i;
			}
			if(s[i] == maxc+'a')
				cur = i;
			if(i-prev==m){
				if(cur>prev){
					cnt++;
					prev = cur;
				}else{
					cnt = -1;
					break;
				}
			}
		}
		if(cnt>=0)
			break;
	}
	maxc += 'a';
//	cout << maxc << " " << cnt << endl;
	vector<char> ans(26);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = cnt;
	for(int i=0;i<ans.size();i++)
		for(int j=0;j<ans[i];j++)
			cout << char(i+'a');
//		cout << string(ans[i],char(i+'a'));
	cout << endl;
//	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;
int m;
string s;
int n;

int check(int maxc){
	int cnt = 0;
	int prev = -1;
	int cur = -1;
	for(int i=0;i<n;i++){
		if(s[i] < maxc+'a'){
			prev = i;
			cur = i;
		}
		if(s[i] == maxc+'a')
			cur = i;
		if(i-prev==m){
			if(cur>prev){
				cnt++;
				prev = cur;
			}else{
				return -1;
			}
		}
	}
	return cnt;
}
int main(){
//	freopen("input.txt","r",stdin);
	cin >> m;
	cin >> s;
	int n = s.length();
	char maxc = 0;
	int cnt = 0;
	int iter = 0;
	for(maxc=0;maxc<26;maxc++){
		int cnt = check(maxc);
		if(cnt==-1)
			continue;
		maxc += 'a';
//	cout << maxc << " " << cnt << endl;
		vector<char> ans(26);
		for(int i=0;i<n;i++){
			if(s[i]<maxc){
				ans[s[i]-'a']++;
			}
		}
		ans[maxc-'a'] = cnt;
		for(int i=0;i<ans.size();i++)
			for(int j=0;j<ans[i];j++)
				cout << char(+'a');
	//		cout << string(ans[i],char(i+'a'));
		cout << endl;
//	}
	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
	int n = s.length();
	char maxc='a';
	int maxcnt = 0;
	int mxpos = 0;
	bool flag = true;
	int iter = 0;
	while(flag){
		char lmn=s[iter];
		int lpos = iter;
		for(int i=iter+1;i<iter+m;i++){
			if(s[i]<=lmn){
				lpos = i;
				lmn = s[i];
			}
		}
		if(lmn==maxc){
			maxcnt++;
		}else if(lmn>maxc){
			maxcnt = 1;
			maxc = lmn;
		}
//		cout << lmn << " " << lpos << endl;
		iter = lpos + 1;
		if(iter+m>=n)
			flag = false;
	}
	vector<char> ans(26);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = maxcnt;
	for(int i=0;i<26;i++)
		cout << string(ans[i],char(i+'a'));
	cout << endl;
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(){
//	freopen("input.txt","r",stdin);
	int m;
	string s;
	cin >> m;
	cin >> s;
	int n = s.length();
	char maxc='a';
	int maxcnt = 0;
	int mxpos = 0;
	int iter = 0;
	while(true){
		char lmn=s[iter];
		int lpos = iter;
		for(int i=iter+1;i<min(n,iter+m);i++){
			if(s[i]<=lmn){
				lpos = i;
				lmn = s[i];
			}
		}
		if(lmn==maxc){
			maxcnt++;
		}else if(lmn>maxc){
			maxcnt = 1;
			maxc = lmn;
		}
//		cout << lmn << " " << lpos << endl;
		iter = lpos + 1;
		if(iter+m>=n-1)
			break;
	}
	vector<char> ans(100);
	for(int i=0;i<n;i++){
		if(s[i]<maxc){
			ans[s[i]-'a']++;
		}
	}
	ans[maxc-'a'] = maxcnt;
	for(int i=0;i<ans.size();i++)
		cout << string(ans[i],char(i+'a'));
	cout << endl;
	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005];
	multiset<char>ans;
	set<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);
	int tam = strlen(str);
	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].insert(i);

	int req = m, best = 0, pt = 0;

	while(req < tam)
	{
		bool flag = false;
		for(int i = 0;i < 26 && !flag;i++)
		{
			if(hash[i].empty() || *(hash[i].begin()) > req)
				continue;

			auto lb = lower_bound(hash[i].begin(), hash[i].end(), req);

			if(lb == hash[i].end())
				lb--;

			if(*lb > req)
				lb--;

			if(*lb + m >= req)
			{
				flag = true;
				req = *lb + m;
				hash[i].erase(lb);
				ans.insert(i+'a');
			}
		}
	}

	auto it = ans.end();
	char last = *(--it);
	for(int i = 0;i < (last-'a');i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			ans.insert(i+'a');

	for(it = ans.begin();it != ans.end();it++)
		printf("%c", *it);
	putchar('\n');
	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005], ans[100005];
	set<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);

	int tam = strlen(str);
	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].insert(i);

	int req = m, pt = 0, maxx = 0;

	while(req < tam)
	{
		bool flag = false;
		for(int i = 0;i < 26 && !flag;i++)
		{
			if(hash[i].empty() || *(hash[i].begin()) > req)
				continue;

			set<int>::iterator lb = lower_bound(hash[i].begin(), hash[i].end(), req);

			if(lb == hash[i].end())
				lb--;

			if(*lb > req)
				lb--;

			if(*lb + m >= req)
			{
				//printf("%d : %d -> %d\n", req, i, *lb);
				flag = true;
				req = *lb + m;
				hash[i].erase(lb);
				ans[pt++] = i+'a';
				maxx = max(maxx, i);
			}
		}
	}

	for(int i = 0;i < maxx;i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			ans[pt++] = i+'a';
	sort(ans, ans+pt);
	ans[pt] = '\0';
	printf("%s\n", ans);

	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005];
	multiset<char>ans;
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);
	int tam = strlen(str);
	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, best = 0, pt = 0;

	while(req < tam)
	{
		bool flag = false;
		for(int i = 0;i < 26 && !flag;i++)
		{
			for(int j = 0;j < (int)hash[i].size();j++)
			{
				if(hash[i][j] <= req)
				{
					if(!used[i][j] && hash[i][j]+m >= req)
					{
						used[i][j] = true;
						flag = true;
						best = j;
					}
				}
				else
					break;
			}
			if(flag)
			{
				req = hash[i][best]+m;
				ans.insert(i+'a');
			}
		}
	}

	auto it = ans.end();
	char last = *(--it);
	for(int i = 0;i < (last-'a');i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
			{
				used[i][j] = true;
				ans.insert(i+'a');
			}

	for(it = ans.begin();it != ans.end();it++)
		printf("%c", *it);
	putchar('\n');
	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005];
	multiset<char>ans;
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);
	int tam = strlen(str);
	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, best = 0, pt = 0;

	while(req < tam)
	{
		bool flag = false;
		for(int i = 0;i < 26 && !flag;i++)
		{
			for(int j = 0;j < (int)hash[i].size();j++)
			{
				if(hash[i][j] <= req)
				{
					if(!used[i][j] && hash[i][j]+m >= req)
					{
						flag = true;
						best = j;
					}
				}
				else
					break;
			}
			if(flag)
			{
				used[i][best] = true;
				req = hash[i][best]+m;
				ans.insert(i+'a');
			}
		}
	}

	auto it = ans.end();
	char last = *(--it);
	for(int i = 0;i < (last-'a');i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
			{
				used[i][j] = true;
				ans.insert(i+'a');
			}

	for(it = ans.begin();it != ans.end();it++)
		printf("%c", *it);
	putchar('\n');
	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005], ans[100005];
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);

	int tam = strlen(str);

	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, pt = 0, maxx = 0;

	while(req <= tam)
	{
		for(int i = 0;i < 26;i++)
		{
			if(hash[i].empty() || hash[i][0] > req)
				continue;

			int lb = lower_bound(hash[i].begin(), hash[i].end(), req) - hash[i].begin();

			if(lb == hash[i].size())
				lb--;

			if(hash[i][lb] > req)
				lb--;

			if(hash[i][lb] + m >= req)
			{
				req = hash[i][lb] + m;
				used[i][lb] = true;
				ans[pt++] = i+'a';
				maxx = max(maxx, i);
				break;
			}
		}
	}

	for(int i = 0;i < maxx;i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
				ans[pt++] = i+'a';
	sort(ans, ans+pt);
	ans[pt] = '\0';
	printf("%s\n", ans);

	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005], ans[100005];
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);

	int tam = strlen(str);

	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, pt = 0, maxx = 0;

	while(req <= tam)
	{
		for(int i = 0;i < 26;i++)
		{
			if(hash[i].empty() || hash[i][0] > req)
				continue;

			int lb = lower_bound(hash[i].begin(), hash[i].end(), req) - hash[i].begin();

			if(lb == hash[i].size())
				lb--;

			if(hash[i][lb] > req)
				lb--;

			if(hash[i][lb] + m >= req && !used[i][lb])
			{
				req = hash[i][lb] + m;
				used[i][lb] = true;
				ans[pt++] = i+'a';
				maxx = max(maxx, i);
				break;
			}
		}
	}

	for(int i = 0;i < maxx;i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
				ans[pt++] = i+'a';
	sort(ans, ans+pt);
	ans[pt] = '\0';
	printf("%s\n", ans);

	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005], ans[100005];
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);

	int tam = strlen(str);
	if(m == tam)
		return 0;

	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, pt = 0, maxx = 0;

	while(req < tam)
	{
		for(int i = 0;i < 26;i++)
		{
			if(hash[i][0] > req)
				continue;

			int lb = lower_bound(hash[i].begin(), hash[i].end(), req) - hash[i].begin();

			if(lb == hash[i].size())
				lb--;

			if(hash[i][lb] > req)
				lb--;

			if(hash[i][lb] + m >= req && !used[i][lb])
			{
				req = hash[i][lb] + m;
				used[i][lb] = true;
				ans[pt++] = i+'a';
				maxx = max(maxx, i);
				break;
			}
		}
	}

	for(int i = 0;i < maxx;i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
				ans[pt++] = i+'a';
	sort(ans, ans+pt);
	ans[pt] = '\0';
	printf("%s\n", ans);

	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005], ans[100005];
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);

	int tam = strlen(str);
	if(m == tam)
	{
		puts("a");
		return 0;
	}
	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, pt = 0, maxx = 0;

	while(req < tam)
	{
		for(int i = 0;i < 26;i++)
		{
			if(hash[i][0] > req)
				continue;

			int lb = lower_bound(hash[i].begin(), hash[i].end(), req) - hash[i].begin();

			if(lb == hash[i].size())
				lb--;

			if(hash[i][lb] > req)
				lb--;

			if(hash[i][lb] + m >= req && !used[i][lb])
			{
				req = hash[i][lb] + m;
				used[i][lb] = true;
				ans[pt++] = i+'a';
				maxx = max(maxx, i);
				break;
			}
		}
	}

	for(int i = 0;i < maxx;i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
				ans[pt++] = i+'a';
	sort(ans, ans+pt);
	ans[pt] = '\0';
	printf("%s\n", ans);

	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005], ans[100005];
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);

	int tam = strlen(str);

	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, pt = 0, maxx = 0;

	while(req <= tam)
	{
		for(int i = 0;i < 26;i++)
		{
			if(hash[i][0] > req)
				continue;

			int lb = lower_bound(hash[i].begin(), hash[i].end(), req) - hash[i].begin();

			if(lb == hash[i].size())
				lb--;

			if(hash[i][lb] > req)
				lb--;

			if(hash[i][lb] + m >= req && !used[i][lb])
			{
				req = hash[i][lb] + m;
				used[i][lb] = true;
				ans[pt++] = i+'a';
				maxx = max(maxx, i);
				break;
			}
		}
	}

	for(int i = 0;i < maxx;i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
				ans[pt++] = i+'a';
	sort(ans, ans+pt);
	ans[pt] = '\0';
	printf("%s\n", ans);

	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005];
	multiset<char>ans;
	set<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);
	int tam = strlen(str);
	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].insert(i);

	int req = m, ant;

	while(req < tam)
	{
		ant = req;
		bool flag = false;
		for(int i = 0;i < 26 && !flag;i++)
		{
			if(hash[i].empty() || *(hash[i].begin()) > req)
				continue;

			auto lb = lower_bound(hash[i].begin(), hash[i].end(), req);

			if(lb == hash[i].end())
				lb--;

			if(*lb > req)
				lb--;

			if(*lb + m >= req)
			{
				//printf("%d : %d -> %d\n", req, i, *lb);
				flag = true;
				req = *lb + m;
				hash[i].erase(lb);
				ans.insert(i+'a');
			}
		}
		if(ant == req)
		{
			puts("fcuk");
			break;
		}
	}

	auto it = ans.end();
	char last = *(--it);
	for(int i = 0;i < (last-'a');i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			ans.insert(i+'a');

	for(it = ans.begin();it != ans.end();it++)
		printf("%c", *it);
	putchar('\n');
	return 0;
}


#include <bits/stdc++.h>
#define pi pair<int,int>
using namespace std;
int main()
{
	int m;
	char str[100005], ans[100005];
	bool used[30][100005] = {};
	vector<int>hash[30];

	scanf("%d", &m);
	scanf("%s", str);

	int tam = strlen(str);
	for(int i = 1;i <= tam;i++)
		hash[str[i-1]-'a'].push_back(i);

	int req = m, pt = 0, maxx = 0;

	while(req < tam)
	{
		for(int i = 0;i < 26;i++)
		{
			if(hash[i][0] > req)
				continue;

			int lb = lower_bound(hash[i].begin(), hash[i].end(), req) - hash[i].begin();

			if(lb == hash[i].size())
				lb--;

			if(hash[i][lb] > req)
				lb--;

			if(hash[i][lb] + m >= req && !used[i][lb])
			{
				req = hash[i][lb] + m;
				used[i][lb] = true;
				ans[pt++] = i+'a';
				maxx = max(maxx, i);
				break;
			}
		}
	}

	for(int i = 0;i < maxx;i++)
		for(int j = 0;j < (int)hash[i].size();j++)
			if(!used[i][j])
				ans[pt++] = i+'a';
	sort(ans, ans+pt);
	ans[pt] = '\0';
	printf("%s\n", ans);

	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define D { p = M[i];  M[i] = t + A[i];  t = max(t , p); }

long long M[1502],A[1502],m,n,i,t,p,h;

int main(){

  cin >> m >> n;

  for(m++;m--;h=!h){
    for(i=1;i<=n;i++){
      scanf("%lld",A+i);
      A[i] += A[i-1];
    }
    t = -100000000011LL;
    if(h)
      for(i=n; i ;i--)  D
    else
      for(i=1;i<=n;i++) D
  }

  cout << t;
}


#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 INF 1000000000000000000ll
#define DIM 100007
#define pll pair<long long, long long>
#define ll long long
#define try cout<<"good"<<endl
#define ld long double
#define fi first
#define se second
#define pb push_back

typedef  pair<  pair<long long, long long>, long long> ppll;
ll res,n,m,c,x,x2,y2,k,e,h,a1,a2,w,a3,y,z,a4,a5,a6,a7,last,dist,LL,timer,start,finish,maxmask,newmax,reslast,tests;
string s1;
ll l,r;

ld d1,d2,d3;
vector <ll> a;
ll mas[1507][1507];
ll sum[1507][1507];
ll prefmax[1507][1507];
ll sufmax[1507][1507];
ll dp[1507][1507];
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        prefmax[i][0]=-INF;
        prefmax[i][1]=-INF;
        sufmax[i][m+1]=-INF;
        sufmax[i][m]=-INF;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>mas[i][j];
            //prefmax[i][j]=max(prefmax[i][j-1],mas[i][j]);
            sum[i][j]=sum[i][j-1]+mas[i][j];
        }
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i%2==1){
                //if(j==1)continue;
                if(i==1){
                    dp[i][j]=sum[i][j];
                }else{
                    dp[i][j]=prefmax[i-1][j-1]+sum[i][j];
                }
            }else{
                dp[i][j]=sufmax[i-1][j+1]+sum[i][j];
            }
        }
        for(int j=m;j>=1;j--){
            sufmax[i][j]=max(sufmax[i][j+1],dp[i][j]);
        }
        for(int j=1;j<=m;j++){
            prefmax[i][j]=max(prefmax[i][j-1],dp[i][j]);
        }
    }
    for(int i=1;i<=m;i++){
        if(n%2==1&&i==1)continue;
        res=max(res,dp[n][i]);
    }
    /*for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<dp[i][j]<<' ';
        }cout<<endl;
    }*/
    cout<<res<<endl;
    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 INF 1000000000000000000ll
#define DIM 100007
#define pll pair<long long, long long>
#define ll long long
#define try cout<<"good"<<endl
#define ld long double
#define fi first
#define se second
#define pb push_back

typedef  pair<  pair<long long, long long>, long long> ppll;
ll res,n,m,c,x,x2,y2,k,e,h,a1,a2,w,a3,y,z,a4,a5,a6,a7,last,dist,LL,timer,start,finish,maxmask,newmax,reslast,tests;
string s1;
ll l,r;

ld d1,d2,d3;
vector <ll> a;
ll mas[1507][1507];
ll sum[1507][1507];
ll prefmax[1507][1507];
ll sufmax[1507][1507];
ll dp[1507][1507];
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        prefmax[i][0]=-INF;
        prefmax[i][1]=-INF;
        sufmax[i][m+1]=-INF;
        sufmax[i][m]=-INF;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>mas[i][j];
            //prefmax[i][j]=max(prefmax[i][j-1],mas[i][j]);
            sum[i][j]=sum[i][j-1]+mas[i][j];
        }
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i%2==1){
                //if(j==1)continue;
                if(i==1){
                    dp[i][j]=sum[i][j];
                }else{
                    dp[i][j]=prefmax[i-1][j-1]+sum[i][j];
                }
            }else{
                dp[i][j]=sufmax[i-1][j+1]+sum[i][j];
            }
        }
        for(int j=m;j>=1;j--){
            sufmax[i][j]=max(sufmax[i][j+1],dp[i][j]);
        }
        for(int j=1;j<=m;j++){
            prefmax[i][j]=max(prefmax[i][j-1],dp[i][j]);
        }
    }
    res=-INF;
    for(int i=1;i<=m;i++){
        if(n%2==1&&i==1)continue;
        res=max(res,dp[n][i]);
    }
    /*for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<dp[i][j]<<' ';
        }cout<<endl;
    }*/
    cout<<res<<endl;
    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 INF 1000000000000000000ll
#define DIM 100007
#define pll pair<long long, long long>
#define ll long long
#define try cout<<"good"<<endl
#define ld long double
#define fi first
#define se second
#define pb push_back

typedef  pair<  pair<long long, long long>, long long> ppll;
ll res,n,m,c,x,x2,y2,k,e,h,a1,a2,w,a3,y,z,a4,a5,a6,a7,last,dist,LL,timer,start,finish,maxmask,newmax,reslast,tests;
string s1;
ll l,r;

ld d1,d2,d3;
vector <ll> a;
ll mas[1507][1507];
ll sum[1507][1507];
ll prefmax[1507][1507];
ll sufmax[1507][1507];
ll dp[1507][1507];
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        prefmax[i][0]=-INF;
        prefmax[i][1]=-INF;
        sufmax[i][m+1]=-INF;
        sufmax[i][m]=-INF;
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>mas[i][j];
            //prefmax[i][j]=max(prefmax[i][j-1],mas[i][j]);
            sum[i][j]=sum[i][j-1]+mas[i][j];
        }
    }

    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i%2==1){
                //if(j==1)continue;
                if(i==1){
                    dp[i][j]=sum[i][j];
                }else{
                    dp[i][j]=prefmax[i-1][j-1]+mas[i][j];
                }
            }else{
                dp[i][j]=sufmax[i-1][j+1]+mas[i][j];
            }
        }
        for(int j=m;j>=1;j--){
            sufmax[i][j]=max(sufmax[i][j+1],dp[i][j]);
        }
        for(int j=1;j<=m;j++){
            prefmax[i][j]=max(prefmax[i][j-1],dp[i][j]);
        }
    }
    for(int i=1;i<=m;i++){
        if(n%2==1&&i==1)continue;
        res=max(res,dp[n][i]);
    }
    /*for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cout<<dp[i][j]<<' ';
        }cout<<endl;
    }*/
    cout<<res<<endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/hash_map>
#include <ext/numeric>
using namespace std;
using namespace __gnu_cxx;

#define EPS      1e-9
#define F        first
#define S        second
#define pi       acos(-1)
#define ll       long long
#define oo       0x3f3f3f3f
#define sz(x)    (int)x.size()
#define sc(x)    scanf("%d",&x)
#define all(x)   x.begin(),x.end()
#define rall(x)  x.rbegin(),x.rend()

const ll OO=1e13;
int n,m;
int arr[1505][1505];
ll dp[1505][1505][2];

ll solve(int i,int j,int op){
  if(j>m||(op&&j==0))return -OO;
  if(i==n)return 0;
  ll &ret=dp[i][j][op];
  if(~ret)return ret;
  if(op==0){
    if(i&1)ret=solve(i,j-1,1);
    else ret=solve(i,j+1,1);
  }else{
    ret=solve(i+1,j,0)+arr[i][j-1];
    if(i&1) ret=max(ret,solve(i,j-1,1));
    else ret=max(ret,solve(i,j+1,1));
  }
  return ret;
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
#endif
  sc(n),sc(m);
  for(int i=0;i<n;++i)
    for(int j=0;j<m;++j){
      sc(arr[i][j]);
      if(j)arr[i][j]+=arr[i][j-1];
    }
  memset(dp,-1,sizeof dp);
  printf("%lld\n",solve(0,0,0));
}


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

const int N = 1502;
const int inf = 1e10;
int dp[N][N];
vector<int> pref(N), suf(N);
signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);
    std::cin.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        int sum = 0;
        for(int j = 1; j <= m; j++) {
            int x; cin >> x;
            sum += x;
            if(i & 1) dp[i][j] = pref[j - 1] + sum;
            else dp[i][j] = suf[j + 1] + sum;
        }
        pref[0] = - inf;
        suf[m + 1] = -inf;
        for(int j = 1; j <= m; j++) pref[j] = max(pref[j - 1], dp[i][j]);
        for(int j = m; j; j--) suf[j] = max(suf[j + 1], dp[i][j]);
    }
    //for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) cout << dp[i][j] << ' '; cout << '\n'; }
    int ans = 0;
    for(int i = 1; i <= m; i++) ans = max(ans, dp[n][i]);
    cout << ans << '\n';
    return 0;
}


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

const int N = 1502;
const int inf = 1e10;
int dp[N][N];
vector<int> pref(N), suf(N);
signed main() {
    std::ios::sync_with_stdio(0);
    std::cout.tie(0);
    std::cin.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        int sum = 0;
        for(int j = 1; j <= m; j++) {
            int x; cin >> x;
            sum += x;
            if(i & 1) dp[i][j] = pref[j - 1] + sum;
            else dp[i][j] = suf[j + 1] + sum;
        }
        pref[0] = - inf;
        suf[m + 1] = -inf;
        for(int j = 1; j <= m; j++) pref[j] = max(pref[j - 1], dp[i][j]);
        for(int j = m; j; j--) suf[j] = max(suf[j + 1], dp[i][j]);
    }
    //for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) cout << dp[i][j] << ' '; cout << '\n'; }
    int ans = -inf;
    for(int i = 1; i <= m; i++) ans = max(ans, dp[n][i]);
    cout << ans << '\n';
    return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1505;
int n,m,s[maxn][maxn];
ll dp[maxn][maxn],l[maxn],r[maxn];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			int a;
			scanf("%d",&a);
			s[i][j]=s[i][j-1]+a;
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			dp[i][j]=-1e18;
	for(int j=2;j<=m;j++)dp[1][j]=s[1][j];
	r[m]=dp[1][m];
	for(int j=m-1;j>=1;j--)r[j]=max(r[j+1],dp[1][j]);
	l[1]=dp[1][1];
	for(int j=2;j<=m;j++)l[j]=max(l[j-1],dp[1][j]);
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if((i&1)&&j>1&&l[j-1]!=-1e18)dp[i][j]=max(dp[i][j],l[j-1]+s[i][j]);
			else if(!(i&1)&&j<m&&r[j+1]!=-1e18)dp[i][j]=max(dp[i][j],r[j+1]+s[i][j]);
		}
		r[m]=dp[i][m];
		for(int j=m-1;j>=1;j--)r[j]=max(r[j+1],dp[i][j]);
		l[1]=dp[i][1];
		for(int j=2;j<=m;j++)l[j]=max(l[j-1],dp[i][j]);
	}
	printf("%I64d\n",l[m]);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1505;
int n,m,s[maxn][maxn];
ll dp[maxn][maxn],l[maxn],r[maxn];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			int a;
			scanf("%d",&a);
			s[i][j]=s[i][j-1]+a;
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			dp[i][j]=-1e18;
	for(int j=1;j<=m;j++)dp[1][j]=s[1][j];
	r[m]=dp[1][m];
	for(int j=m-1;j>=1;j--)r[j]=max(r[j+1],dp[1][j]);
	l[1]=dp[1][1];
	for(int j=2;j<=m;j++)l[j]=max(l[j-1],dp[1][j]);
	for(int i=2;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			if((i&1)&&j>1)dp[i][j]=max(dp[i][j],l[j-1]+s[i][j]);
			else if(!(i&1)&&j<m)dp[i][j]=max(dp[i][j],r[j+1]+s[i][j]);
			r[m]=dp[i][m];
			for(int j=m-1;j>=1;j--)r[j]=max(r[j+1],dp[i][j]);
			l[1]=dp[i][1];
			for(int j=2;j<=m;j++)l[j]=max(l[j-1],dp[i][j]);
		}
	ll ans=-1e18;
	for(int j=1;j<=m;j++)ans=max(ans,dp[n][j]);
	printf("%I64d\n",ans);
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1505;
int n,m,s[maxn][maxn];
ll dp[maxn][maxn],l[maxn],r[maxn];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			int a;
			scanf("%d",&a);
			s[i][j]=s[i][j-1]+a;
		}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			dp[i][j]=-1e18;
	for(int j=1;j<=m;j++)dp[1][j]=s[1][j];
	r[m]=dp[1][m];
	for(int j=m-1;j>=1;j--)r[j]=max(r[j+1],dp[1][j]);
	l[1]=dp[1][1];
	for(int j=2;j<=m;j++)l[j]=max(l[j-1],dp[1][j]);
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if((i&1)&&j>1&&l[j-1]!=-1e18)dp[i][j]=max(dp[i][j],l[j-1]+s[i][j]);
			else if(!(i&1)&&j<m&&r[j+1]!=-1e18)dp[i][j]=max(dp[i][j],r[j+1]+s[i][j]);
		}
		r[m]=dp[i][m];
		for(int j=m-1;j>=1;j--)r[j]=max(r[j+1],dp[i][j]);
		l[1]=dp[i][1];
		for(int j=2;j<=m;j++)l[j]=max(l[j-1],dp[i][j]);
	}
	printf("%I64d\n",l[n]);
	return 0;
}


#include "bits/stdc++.h"

using namespace std;
using ll = long long;

int main() {
//	ios::sync_with_stdio(0);
//	cin.tie(0);
//	cout.tie(0);
	int n, m;
	cin >> n >> m;
	vector<vector<ll>> a(n, vector<ll>(m));
	for (auto &i: a)
		for (auto &j:i)
			cin >> j;
	vector<vector<ll>> sum(n, vector<ll>(m));
	vector<ll> prefix(m, -INT_MAX), suffix(m, -INT_MAX);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			sum[i][j] = ((j >= 1) ? sum[i][j - 1] : 0) + a[i][j];
		}
	}
	vector<vector<ll>> dp(n, vector<ll>(m, -INT_MAX));
	dp[0] = sum[0];
	for (int i = 0; i < n; i++) {
		if (i != 0)
			for (int j = 0; j < m; j++) {
				if (i & 1) {
					dp[i][j] = ((j < m - 1) ? suffix[j + 1] : -INT_MAX) + sum[i][j];
				} else {
					dp[i][j] = ((j >= 1) ? prefix[j - 1] : -INT_MAX) + sum[i][j];
				}
			}
		for (int j = 0; j < m; j++) {
			prefix[j] = max((j >= 1) ? prefix[j - 1] : dp[i][0], dp[i][j]);
		}
		for (int j = m - 1; j >= 0; j--) {
			suffix[j] = max((j != m - 1) ? suffix[j + 1] : dp[i][m - 1], dp[i][j]);
		}
	}
	cout << prefix[m - 1] << '\n';
}


#include "bits/stdc++.h"

using namespace std;
using ll = long long;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	vector<vector<ll>> a(n, vector<ll>(m));
	for (auto &i: a)
		for (auto &j:i)
			cin >> j;
	vector<vector<ll>> sum(n, vector<ll>(m));
	vector<ll> prefix(m, -INT_MAX), suffix(m, -INT_MAX);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			sum[i][j] = ((j >= 1) ? sum[i][j - 1] : 0) + a[i][j];
		}
	}
	vector<vector<ll>> dp(n, vector<ll>(m, -INT_MAX));
	dp[0] = sum[0];
	for (int i = 0; i < n; i++) {
		if (i != 0)
			for (int j = 0; j < m; j++) {
				if (i & 1) {
					dp[i][j] = ((j < m - 1) ? suffix[j + 1] : -INT_MAX) + sum[i][j];
				} else {
					dp[i][j] = ((j >= 1) ? prefix[j - 1] : -INT_MAX) + sum[i][j];
				}
			}
		for (int j = 0; j < m; j++) {
			prefix[j] = max((j >= 1) ? prefix[j - 1] : dp[i][0], dp[i][j]);
		}
		for (int j = m - 1; j >= 0; j--) {
			suffix[j] = max((j != m - 1) ? suffix[j + 1] : dp[i][m - 1], dp[i][j]);
		}
	}
	cout << prefix[m - 1] << '\n';
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
ll n, m;
ll dp[1501][1501];
ll a[1510][1501];
ll func(ll here, ll here1)
{
	if (here1 > m)return -999999999999999;
	if (here1 < 1)return -999999999999999;
	if (here == n + 1)return 0;
	ll &ret = dp[here][here1];
	if (ret != -1)return ret;
	ret= -999999999999999;
	if (here % 2)
	{
		ret = max(ret, func(here, here1 + 1));
		ret = max(ret, func(here + 1, here1 - 1)+a[here][here1]);
	}
	else
	{
		ret = max(ret, func(here, here1 - 1));
		ret = max(ret, func(here + 1, here1 + 1) + a[here][here1]);
	}
	return ret;
}
int main()
{
	memset(dp, -1, sizeof(dp));
	scanf("%lld %lld", &n, &m);
	for (int i = 1; i <= n; i++) {
		for (int y = 1; y <= m; y++) {
			scanf("%lld", &a[i][y]);
			a[i][y] += a[i][y - 1];
		}
	}
	printf("%lld\n", func(1, 1));
}


#include<bits/stdc++.h>

using namespace std;

long long n,m,dp[1505][1505],a[1505][1505],c[1505][1505],prefmaxc[1505][1505],suffmaxc[1505][1505];
int main(){
    cin.tie(0),cout.tie(0),ios::sync_with_stdio(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            c[i][j]=a[i][j];
        }
    }
    for(int i=0;i<=n+1;i++){
        for(int j=0;j<=m+1;j++){
            prefmaxc[i][j]=-LLONG_MAX;
            suffmaxc[i][j]=-LLONG_MAX;
            dp[i][j]=-LLONG_MAX;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            c[i][j]+=c[i][j-1];
    }
    for(int j=1;j<=m;j++){
        dp[1][j]=c[1][j];
        prefmaxc[1][j]=max(prefmaxc[1][j-1],dp[1][j]);
    }
    for(int j=m;j>=1;j--)
        suffmaxc[1][j]=max(suffmaxc[1][j+1],dp[1][j]);
    for(int i=2;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i%2==0){
                if(j+1<=m)
                dp[i][j]=suffmaxc[i-1][j+1]+c[i][j];
                else
                dp[i][j]=c[i][j];
            }
            else{
                if(j-1>=1)
                dp[i][j]=prefmaxc[i-1][j-1]+c[i][j];
                else
                dp[i][j]=c[i][j];
            }
        }
        for(int j=1;j<=m;j++)
            prefmaxc[i][j]=max(prefmaxc[i][j-1],dp[i][j]);
        for(int j=m;j>=1;j--)
            suffmaxc[i][j]=max(suffmaxc[i][j+1],dp[i][j]);
    }
    long long max1=-LLONG_MAX;
    if(n%2==0){
        for(int j=1;j<=m-1;j++)
            max1=max(max1,dp[n][j]);
    }
    else{
        for(int j=2;j<=m;j++)
            max1=max(max1,dp[n][j]);
    }
    cout<<max1;
}


#include <iostream>
#include <limits>
#include <algorithm>

using namespace std;

const int N = 1500;
int a[N][N];
long long profit[N][N];

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

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

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      cin >> a[i][j];
    }
  }

  for (int i = 0; i < n; ++i) {
    for (int j = 1; j < m; ++j) {
      a[i][j] += a[i][j - 1];
    }
  }

  for (int j = 0; j < m; ++j) {
    profit[0][j] = a[0][j];
  }
  for (int i = 1; i < n; ++i) {
    if (i % 2) { // нахождение нижней части
      for (int j = 0; j < m; ++j) {
        profit[i][j] = numeric_limits<long long>::min();
        for (int k = j + 1; k < m; ++k) {
          profit[i][j] = max(a[i][j] + profit[i - 1][k], profit[i][j]);
        }
      }
    } else { // нахождение верхней части
      for (int j = 0; j < m; ++j) {
        profit[i][j] = numeric_limits<long long>::min();
        for (int k = 0; k < j; ++k) {
          profit[i][j] = max(a[i][j] + profit[i - 1][k], profit[i][j]);
        }
      }
    }
  }

  long long ans = numeric_limits<long long>::min();
  for (int j = 0; j < m; ++j) {
    ans = max(ans, profit[n - 1][j]);
  }
  cout << ans;

  return 0;
}


#include <iostream>
#include <limits>
#include <algorithm>

using namespace std;

const int INF = numeric_limits<long long>::min();
const int N = 1500;
int a[N][N];
long long profit[N][N];

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

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

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      cin >> a[i][j];
    }
  }

  for (int i = 0; i < n; ++i) {
    for (int j = 1; j < m; ++j) {
      a[i][j] += a[i][j - 1];
    }
  }

  for (int j = 0; j < m; ++j) {
    profit[0][j] = a[0][j];
  }
  for (int i = 1; i < n; ++i) {
    if (i % 2) { // нахождение нижней части
      for (int j = 0; j < m; ++j) {
        profit[i][j] = INF;
        for (int k = j + 1; k < m; ++k) {
          profit[i][j] = max(a[i][j] + profit[i - 1][k], profit[i][j]);
        }
      }
    } else { // нахождение верхней части
      for (int j = 0; j < m; ++j) {
        profit[i][j] = INF;
        for (int k = 0; k < j; ++k) {
          profit[i][j] = max(a[i][j] + profit[i - 1][k], profit[i][j]);
        }
      }
    }
  }

  long long ans = INF;
  for (int j = 0; j < m; ++j) {
    ans = max(ans, profit[n - 1][j]);
  }
  cout << ans;

  return 0;
}


#include <iostream>
#include <limits>
#include <algorithm>

using namespace std;

const int N = 1500;
int a[N][N];
long long profit[N][N];

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

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

  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      cin >> a[i][j];
    }
  }

  for (int i = 0; i < n; ++i) {
    for (int j = 1; j < m; ++j) {
      a[i][j] += a[i][j - 1];
    }
  }

  for (int j = 0; j < m; ++j) {
    profit[0][j] = a[0][j];
  }
  for (int i = 1; i < n; ++i) {
    if (i % 2) { // нахождение нижней части
      profit[i][m - 1] = numeric_limits<long long>::min();
      profit[i][m - 2] = a[i][m - 2] + profit[i - 1][m - 1];
      for (int j = m - 3; j >= 0; --j) {
        profit[i][j] = max(profit[i][j + 1] - a[i][j + 1] + a[i][j], a[i][j] + profit[i - 1][j + 1]);
      }

    } else {
      profit[i][0] = numeric_limits<long long>::min();
      profit[i][1] = profit[i - 1][0] + a[i][1];
      for (int j = 2; j < m; ++j) {
        profit[i][j] = max(profit[i][j - 1] - a[i][j - 1] + a[i][j], a[i][j] + profit[i - 1][j - 1]);
      }
    }
  }

  long long ans = numeric_limits<long long>::min();
  for (int j = 0; j < m; ++j) {
    ans = max(ans, profit[n - 1][j]);
  }
  cout << ans;

  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits.h>
#include <cfloat>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cassert>
using namespace std;
#define mem(flag) memset(flag,0,sizeof(flag))
#define Mem(flag) memset(flag,-1,sizeof(flag))
#define read(a) a=getInt()
#define En printf("\n")
#define P(a) printf("%d ",a)
#define Pn(a) printf("%d\n",a)
#define dbg(x) cout << (#x) << " = " << (x) << endl

const int MAX = 1550;

struct seg {
#define left(i) 2 * i + 1
#define right(i) 2 * i + 2
    struct node {
        int key;
    };
    node an[4 * MAX];
    void maintain(int i) {
        an[i].key = std::max(an[left(i)].key, an[right(i)].key);
    }
    int query(int root, int l, int r, int nl, int nr) {
        if (r < nl || l > nr) return INT_MIN;
        else if (nl <= l && r <= nr) return an[root].key;
        else {
            int mid = (l + r) / 2;
            return std::max(query(left(root), l, mid, nl, nr), query(right(root), mid + 1, r, nl, nr));
        }
    }
    void update(int root, int l, int r, int idx, int v) {
        if (l == r && l == idx) {
            an[root].key = v;
        } else if (r < idx || l > idx) return ;
        else {
            int mid = (l + r) / 2;
            update(left(root), l, mid, idx, v);
            update(right(root), mid + 1, r, idx, v);
            maintain(root);
        }
    }
};

int mm[MAX][MAX];
int dp[MAX][MAX];
int n, m;
seg tree[MAX];

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            scanf("%d", &mm[i][j]);
            if (j != 1) mm[i][j] += mm[i][j - 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i == 1) {
                dp[i][j] = mm[i][j];
                tree[i].update(0, 1, m, j, dp[i][j]);
            } else {
                if (i % 2 == 0) {
                    if (j == m) {
                        dp[i][j] = INT_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, j + 1, m);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                } else {
                    if (j == 1) {
                        dp[i][j] = INT_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, 1, j - 1);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                }
            }
        }
    }
    int ans = INT_MIN;
    for (int j = 1; j <= m; j++)
        ans = std::max(ans, dp[n][j]);
    //for (int i = 1; i <= n; ++i) {
        //for (int j = 1; j <= m; ++j) {
            //printf("%d ", dp[i][j]);
        //}
        //En;
    //}
    if (ans == INT_MIN) printf("0\n");
    else printf("%d\n", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits.h>
#include <cfloat>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cassert>
using namespace std;
#define mem(flag) memset(flag,0,sizeof(flag))
#define Mem(flag) memset(flag,-1,sizeof(flag))
#define read(a) a=getInt()
#define En printf("\n")
#define P(a) printf("%d ",a)
#define Pn(a) printf("%d\n",a)
#define dbg(x) cout << (#x) << " = " << (x) << endl

typedef long long ll;

const int MAX = 1550;

struct seg {
#define left(i) 2 * i + 1
#define right(i) 2 * i + 2
    struct node {
        ll key;
    };
    node an[4 * MAX];
    void maintain(int i) {
        an[i].key = std::max(an[left(i)].key, an[right(i)].key);
    }
    ll query(int root, int l, int r, int nl, int nr) {
        if (r < nl || l > nr) return INT_MIN;
        else if (nl <= l && r <= nr) return an[root].key;
        else {
            int mid = (l + r) / 2;
            return std::max(query(left(root), l, mid, nl, nr), query(right(root), mid + 1, r, nl, nr));
        }
    }
    void update(int root, int l, int r, int idx, int v) {
        if (l == r && l == idx) {
            an[root].key = v;
        } else if (r < idx || l > idx) return ;
        else {
            int mid = (l + r) / 2;
            update(left(root), l, mid, idx, v);
            update(right(root), mid + 1, r, idx, v);
            maintain(root);
        }
    }
};

ll mm[MAX][MAX];
ll dp[MAX][MAX];
int n, m;
seg tree[MAX];

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            scanf("%lld", &mm[i][j]);
            if (j != 1) mm[i][j] += mm[i][j - 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i == 1) {
                dp[i][j] = mm[i][j];
                tree[i].update(0, 1, m, j, dp[i][j]);
            } else {
                if (i % 2 == 0) {
                    if (j == m) {
                        dp[i][j] = LLONG_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, j + 1, m);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                } else {
                    if (j == 1) {
                        dp[i][j] = LLONG_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, 1, j - 1);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                }
            }
        }
    }
    ll ans = LLONG_MIN;
    for (int j = 1; j <= m; j++)
        ans = std::max(ans, dp[n][j]);
    //for (int i = 1; i <= n; ++i) {
        //for (int j = 1; j <= m; ++j) {
            //printf("%d ", dp[i][j]);
        //}
        //En;
    //}
    if (ans == LLONG_MIN) printf("0\n");
    else printf("%lld\n", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits.h>
#include <cfloat>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cassert>
using namespace std;
#define mem(flag) memset(flag,0,sizeof(flag))
#define Mem(flag) memset(flag,-1,sizeof(flag))
#define read(a) a=getInt()
#define En printf("\n")
#define P(a) printf("%d ",a)
#define Pn(a) printf("%d\n",a)
#define dbg(x) cout << (#x) << " = " << (x) << endl

const int MAX = 1550;

struct seg {
#define left(i) 2 * i + 1
#define right(i) 2 * i + 2
    struct node {
        int key;
    };
    node an[4 * MAX];
    void maintain(int i) {
        an[i].key = std::max(an[left(i)].key, an[right(i)].key);
    }
    int query(int root, int l, int r, int nl, int nr) {
        if (r < nl || l > nr) return INT_MIN;
        else if (nl <= l && r <= nr) return an[root].key;
        else {
            int mid = (l + r) / 2;
            return std::max(query(left(root), l, mid, nl, nr), query(right(root), mid + 1, r, nl, nr));
        }
    }
    void update(int root, int l, int r, int idx, int v) {
        if (l == r && l == idx) {
            an[root].key = v;
        } else if (r < idx || l > idx) return ;
        else {
            int mid = (l + r) / 2;
            update(left(root), l, mid, idx, v);
            update(right(root), mid + 1, r, idx, v);
            maintain(root);
        }
    }
};

int mm[MAX][MAX];
int dp[MAX][MAX];
int n, m;
seg tree[MAX];

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            scanf("%d", &mm[i][j]);
            if (j != 1) mm[i][j] += mm[i][j - 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i == 1) {
                dp[i][j] = mm[i][j];
                tree[i].update(0, 1, m, j, dp[i][j]);
            } else {
                if (i % 2 == 0) {
                    if (j == m) {
                        dp[i][j] = -1;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, j + 1, m);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                } else {
                    if (j == 1) {
                        dp[i][j] = -1;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, 1, j - 1);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                }
            }
        }
    }
    int ans = -1;
    for (int j = 1; j <= m; j++)
        ans = std::max(ans, dp[n][j]);
    if (ans == -1) printf("0\n");
    else printf("%d\n", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits.h>
#include <cfloat>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cassert>
using namespace std;
#define mem(flag) memset(flag,0,sizeof(flag))
#define Mem(flag) memset(flag,-1,sizeof(flag))
#define read(a) a=getInt()
#define En printf("\n")
#define P(a) printf("%d ",a)
#define Pn(a) printf("%d\n",a)
#define dbg(x) cout << (#x) << " = " << (x) << endl

const int MAX = 1550;

struct seg {
#define left(i) 2 * i + 1
#define right(i) 2 * i + 2
    struct node {
        int key;
    };
    node an[4 * MAX];
    void maintain(int i) {
        an[i].key = std::max(an[left(i)].key, an[right(i)].key);
    }
    int query(int root, int l, int r, int nl, int nr) {
        if (r < nl || l > nr) return INT_MIN;
        else if (nl <= l && r <= nr) return an[root].key;
        else {
            int mid = (l + r) / 2;
            return std::max(query(left(root), l, mid, nl, nr), query(right(root), mid + 1, r, nl, nr));
        }
    }
    void update(int root, int l, int r, int idx, int v) {
        if (l == r && l == idx) {
            an[root].key = v;
        } else if (r < idx || l > idx) return ;
        else {
            int mid = (l + r) / 2;
            update(left(root), l, mid, idx, v);
            update(right(root), mid + 1, r, idx, v);
            maintain(root);
        }
    }
};

int mm[MAX][MAX];
int dp[MAX][MAX];
int n, m;
seg tree[MAX];

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            scanf("%d", &mm[i][j]);
            if (j != 1) mm[i][j] += mm[i][j - 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i == 1) {
                dp[i][j] = mm[i][j];
                tree[i].update(0, 1, m, j, dp[i][j]);
            } else {
                if (i % 2 == 0) {
                    if (j == m) {
                        dp[i][j] = INT_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, j + 1, m);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                } else {
                    if (j == 1) {
                        dp[i][j] = INT_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, 1, j - 1);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                }
            }
        }
    }
    int ans = INT_MIN;
    for (int j = 1; j <= m; j++)
        ans = std::max(ans, dp[n][j]);
    //for (int i = 1; i <= n; ++i) {
        //for (int j = 1; j <= m; ++j) {
            //printf("%d ", dp[i][j]);
        //}
        //En;
    //}
    if (ans == -1) printf("0\n");
    else printf("%d\n", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits.h>
#include <cfloat>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cassert>
using namespace std;
#define mem(flag) memset(flag,0,sizeof(flag))
#define Mem(flag) memset(flag,-1,sizeof(flag))
#define read(a) a=getInt()
#define En printf("\n")
#define P(a) printf("%d ",a)
#define Pn(a) printf("%d\n",a)
#define dbg(x) cout << (#x) << " = " << (x) << endl

typedef long long ll;

const int MAX = 1550;

struct seg {
#define left(i) 2 * i + 1
#define right(i) 2 * i + 2
    struct node {
        ll key;
    };
    node an[4 * MAX];
    void maintain(int i) {
        an[i].key = std::max(an[left(i)].key, an[right(i)].key);
    }
    ll query(int root, int l, int r, int nl, int nr) {
        if (r < nl || l > nr) return INT_MIN;
        else if (nl <= l && r <= nr) return an[root].key;
        else {
            int mid = (l + r) / 2;
            return std::max(query(left(root), l, mid, nl, nr), query(right(root), mid + 1, r, nl, nr));
        }
    }
    void update(int root, int l, int r, int idx, ll v) {
        if (l == r && l == idx) {
            an[root].key = v;
        } else if (r < idx || l > idx) return ;
        else {
            int mid = (l + r) / 2;
            update(left(root), l, mid, idx, v);
            update(right(root), mid + 1, r, idx, v);
            maintain(root);
        }
    }
};

ll mm[MAX][MAX];
ll dp[MAX][MAX];
int n, m;
seg tree[MAX];

int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            scanf("%lld", &mm[i][j]);
            if (j != 1) mm[i][j] += mm[i][j - 1];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= m; ++j) {
            if (i == 1) {
                dp[i][j] = mm[i][j];
                tree[i].update(0, 1, m, j, dp[i][j]);
            } else {
                if (i % 2 == 0) {
                    if (j == m) {
                        dp[i][j] = LLONG_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, j + 1, m);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                } else {
                    if (j == 1) {
                        dp[i][j] = LLONG_MIN;
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    } else {
                        dp[i][j] = mm[i][j] + tree[i - 1].query(0, 1, m, 1, j - 1);
                        tree[i].update(0, 1, m, j, dp[i][j]);
                    }
                }
            }
        }
    }
    ll ans = LLONG_MIN;
    for (int j = 1; j <= m; j++)
        ans = std::max(ans, dp[n][j]);
    //for (int i = 1; i <= n; ++i) {
        //for (int j = 1; j <= m; ++j) {
            //printf("%d ", dp[i][j]);
        //}
        //En;
    //}
    if (ans == LLONG_MIN) printf("0\n");
    else printf("%lld\n", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string.h>
#include <limits.h>
#include <cfloat>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
#include <cassert>
using namespace std;
#define mem(flag) memset(flag,0,sizeof(flag))
#define Mem(flag) memset(flag,-1,sizeof(flag))
#define read(a) a=getInt()
#define En printf("\n")
#define P(a) printf("%d ",a)
#define Pn(a) printf("%d\n",a)
#define dbg(x) cout << (#x) << " = " << (x) << endl

const int MAX = 1020, MAX2 = 2050;

struct nod {
    int hid, knum;
    vector<int> keys;
};

nod orir[MAX], newr[MAX];
vector<int> fs[MAX], ccsj[MAX2];

int oriwho[MAX], curwho[MAX];

int vist[MAX], cc[MAX], cnt, vcnt[MAX2], vnum, se[MAX][2];
int head[MAX], to[MAX << 1], nxt[MAX << 1], exi[MAX << 1], ent;

int n, m, k;

void add(int a, int b) {
   to[ent] = b, nxt[ent] = head[a], head[a] = ent++;
   to[ent] = a, nxt[ent] = head[b], head[b] = ent++;
}

void dfs(int v) {
    vist[v] = 1;
    if (cc[v] != -1) {
        if (!vcnt[cc[v]]) vcnt[cc[v]] = 1, vnum++;
    }
    for (int i = head[v]; ~i; i = nxt[i]) {
        int u = to[i];
        if (exi[i] && !vist[u]) dfs(u);
    }
}

void dfs2(int v) {
    vist[v] = 1, cc[v] = cnt;
    for (int i = head[v]; ~i; i = nxt[i]) {
        int u = to[i];
        if (exi[i] && !vist[u]) dfs2(u);
    }
}

int main() {
    scanf("%d %d %d", &n, &m, &k);
    Mem(head);
    for (int i = 1; i <= m; ++i) {
        int a, b;
        scanf("%d%d", &a, &b);
        add(a, b);
        se[i][0] = ent - 2, se[i][1] = ent - 1;
    }
    char buff[50];
    for (int i = 1; i <= k; ++i) {
        getchar();
        scanf("%s %d %d ", buff, &orir[i].hid, &orir[i].knum);
        for (int j = 0; j < orir[i].knum; ++j) {
            int a; scanf("%d", &a);
           orir[i].keys.push_back(a);
           fs[orir[i].hid].push_back(a);
           oriwho[a] = i;
        }
    }
    for (int i = 1; i <= k; ++i) {
        scanf("%s", buff);
        scanf("%d%d", &newr[i].hid, &newr[i].knum);
        for (int j = 0; j < newr[i].knum; ++j) {
            int a; scanf("%d", &a);
           newr[i].keys.push_back(a);
           curwho[a] = i;
        }
    }
    int orivnum;
    Mem(cc);
    for (int i = 1; i <= n; ++i) {
        if (fs[i].size() != 0) {
            mem(exi); mem(vcnt); vnum = 0;
            for (int j = 0; j < fs[i].size(); ++j) {
                exi[se[fs[i][j]][0]] = exi[se[fs[i][j]][1]] = 1;
                ccsj[cnt].push_back(fs[i][j]);
            }
            do {
                for (int j = 0; j < MAX2; ++j) {
                    if (vcnt[j]) {
                        for (int k = 0; k < ccsj[j].size(); k++)
                            exi[se[ccsj[j][k]][0]] = exi[se[ccsj[j][k]][1]] = 1;
                    }
                }
                orivnum = vnum;
                mem(vist);
                dfs(i);
            } while (vnum != orivnum);
            for (int j = 0; j < MAX2; ++j) {
                if (vcnt[j]) {
                    for (int k = 0; k < ccsj[j].size(); ++k) ccsj[cnt].push_back(ccsj[j][k]);
                }
            }
            mem(vist);
            dfs2(i); cnt++;
        }
        printf("cc = : "); for (int i = 1; i <= n; ++i) P(cc[i]); En;
    }
    bool ok = 1;
    for (int i = 1; i <= k; ++i) {
        int curf = newr[i].hid, orif = orir[i].hid;
        if (curf != orif) {
            if (cc[curf] == -1 || cc[orif] == -1 || cc[curf] != cc[orif]) ok = 0;
        }
        for (int j = 0; j < newr[i].keys.size(); ++j) {
            int a = newr[i].keys[j];
            if (oriwho[a] != curwho[a]) {
                int h1 = orir[oriwho[a]].hid, h2 = orir[curwho[a]].hid;
                if (h1 != h2) {
                    if (cc[h1] == -1 || cc[h2] == -1 || cc[h1] != cc[h2]) ok = 0;
                }
            }
        }
    }
    if (ok) printf("YES\n");
    else printf("NO\n");
    return 0;
}


/* Worldwide Combos, free and competitive block-stacking game!
https://www.worldwide-combos.com */

#include<iostream>
#include<vector>
#include<array>
#include<string>
#include<sstream>
#include<map>
#include<unordered_map>
#include<chrono>
#include<set>
#include<unordered_set>
#include<ctime>
#include<bitset>
#include<queue>
#include<deque>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<random>
#include<cassert>
#include<complex>
#include<fstream>
#include<pthread.h>

#pragma GCC optimize "-O3"
#pragma GCC target "tune=native"

#define fin(i,n) for (int i = 0; i < n; i++)
#define fin2(i,a,b) for (int i = a; i < b; i++)
#define ford(i,n) for (int i = n-1; i >= 0; i--)
#define ford2(i,a,b) for (int i = b-1; i >= a; i--)

#define mp make_pair
#define mt make_tuple
#define pb push_back
#define mod 998244353
#define PI 3.1415926535897932384626
#define EXP1 2.718281828459045

#define si(n) scanf("%d", &n)
#define sii(n,m) scanf("%d %d", &n, &m)
#define siii(n,m,k) scanf("%d %d %d", &n, &m, &k)
#define sl(n) scanf("%lld", &n)
#define sll(n,m) scanf("%lld %lld", &n, &m)
#define slll(n,m,k) scanf("%lld %lld %lld", &n, &m, &k)
#define sd(n) scanf("%lf", &n)
#define sdd(n,m) scanf("%lf %lf", &n, &m)
#define sddd(n,m,k) scanf("%lf %lf %lf", &n, &m, &k)
#define sc(c) scanf("%c", &c)
#define ss(s) scanf("%s", s)
#define sai(t,n) fin(iz,n) { scanf("%d", &t[iz]); }
#define sal(t,n) fin(iz,n) { scanf("%lld", &t[iz]); }
#define sad(t,n) fin(iz,n) { scanf("%lf", &t[iz]); }

#define pc(n) printf("%c\n", n)
#define ps(s) printf("%s\n", s)
#define pi(n) printf("%d\n", n)
#define pii(n,m) printf("%d %d\n", n, m)
#define piii(n,m,k) printf("%d %d %d\n", n, m, k)
#define pl(n) printf("%lld\n", n)
#define pll(n,m) printf("%lld %lld\n", n, m)
#define plll(n,m,k) printf("%lld %lld %lld\n", n, m, k)
#define pd(n) printf("%lf\n", n)
#define pdd(n,m) printf("%lf %lf\n", n, m)
#define pai(t,n) fin(rz,n) { printf("%d ", t[rz]); } printf("\n")
#define pal(t,n) fin(rz,n) { printf("%lld ", t[rz]); } printf("\n")
#define pad(t,n) fin(rz,n) { printf("%lf ", t[rz]); } printf("\n")

#define OK ps("OK")
#define OK1 ps("OK1")
#define OK2 ps("OK2")

#define L long long int
#define D double
#define PII pair<int, int>
#define VPII vector<PII>
#define VVPII vector<VPII>
#define VL vector<L>
#define VI vector<int>
#define VVI vector<VI>
#define VD vector<D>
#define VVD vector<VD>
#define VVPII vector<VPII>
#define VC vector<char>

using namespace std;

L a[1500][1500], res[1500][1500] = {0}, mx[1500][1500] = {0};

int main() {
    int n, m;
    sii(n, m);
    fin(i, n) { sal(a[i], m); }
    fin(i, n) {
        fin2(j, 1, m) {
            a[i][j] += a[i][j-1];
        }
    }
    fin(j, m) { res[0][j] = a[0][j]; }
    fin(i, n) {
        if (i % 2 == 0) {
            mx[i][m-1] = a[i][m-1];
            ford(j, m-1) {
                mx[i][j] = max(mx[i][j+1], a[i][j]);
            }
        }
        else {
            mx[i][0] = a[i][0];
            fin2(j, 1, m) {
                mx[i][j] = max(mx[i][j-1], a[i][j]);
            }
        }
    }
    fin(i, n) {
        fin(j, m) { res[i][j] = -pow(10, 18); }
    }
    //fin(i, n) { pal(a[i], m); }
    //fin(i, n) { pal(mx[i], m); }
    fin(j, m) { res[0][j] = mx[0][j]; }
    fin2(i, 1, n) {
        if (i % 2) {
            ford(j, m-1) {
                res[i][j] = max(res[i][j+1], a[i][j]+res[i-1][j+1]);
            }
        }
        else {
            fin2(j, 1, m) {
                res[i][j] = max(res[i][j-1], a[i][j]+res[i-1][j-1]);
            }
        }
    }
    if (n % 2 == 0) { pl(res[n-1][0]); }
    else { pl(res[n-1][m-1]); }
}


/* Worldwide Combos, free and competitive block-stacking game!
https://www.worldwide-combos.com */

#include<iostream>
#include<vector>
#include<array>
#include<string>
#include<sstream>
#include<map>
#include<unordered_map>
#include<chrono>
#include<set>
#include<unordered_set>
#include<ctime>
#include<bitset>
#include<queue>
#include<deque>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<random>
#include<cassert>
#include<complex>
#include<fstream>
#include<pthread.h>

#pragma GCC optimize "-O3"
#pragma GCC target "tune=native"

#define fin(i,n) for (int i = 0; i < n; i++)
#define fin2(i,a,b) for (int i = a; i < b; i++)
#define ford(i,n) for (int i = n-1; i >= 0; i--)
#define ford2(i,a,b) for (int i = b-1; i >= a; i--)

#define mp make_pair
#define mt make_tuple
#define pb push_back
#define mod 998244353
#define PI 3.1415926535897932384626
#define EXP1 2.718281828459045

#define si(n) scanf("%d", &n)
#define sii(n,m) scanf("%d %d", &n, &m)
#define siii(n,m,k) scanf("%d %d %d", &n, &m, &k)
#define sl(n) scanf("%lld", &n)
#define sll(n,m) scanf("%lld %lld", &n, &m)
#define slll(n,m,k) scanf("%lld %lld %lld", &n, &m, &k)
#define sd(n) scanf("%lf", &n)
#define sdd(n,m) scanf("%lf %lf", &n, &m)
#define sddd(n,m,k) scanf("%lf %lf %lf", &n, &m, &k)
#define sc(c) scanf("%c", &c)
#define ss(s) scanf("%s", s)
#define sai(t,n) fin(iz,n) { scanf("%d", &t[iz]); }
#define sal(t,n) fin(iz,n) { scanf("%lld", &t[iz]); }
#define sad(t,n) fin(iz,n) { scanf("%lf", &t[iz]); }

#define pc(n) printf("%c\n", n)
#define ps(s) printf("%s\n", s)
#define pi(n) printf("%d\n", n)
#define pii(n,m) printf("%d %d\n", n, m)
#define piii(n,m,k) printf("%d %d %d\n", n, m, k)
#define pl(n) printf("%lld\n", n)
#define pll(n,m) printf("%lld %lld\n", n, m)
#define plll(n,m,k) printf("%lld %lld %lld\n", n, m, k)
#define pd(n) printf("%lf\n", n)
#define pdd(n,m) printf("%lf %lf\n", n, m)
#define pai(t,n) fin(rz,n) { printf("%d ", t[rz]); } printf("\n")
#define pal(t,n) fin(rz,n) { printf("%lld ", t[rz]); } printf("\n")
#define pad(t,n) fin(rz,n) { printf("%lf ", t[rz]); } printf("\n")

#define OK ps("OK")
#define OK1 ps("OK1")
#define OK2 ps("OK2")

#define L long long int
#define D double
#define PII pair<int, int>
#define VPII vector<PII>
#define VVPII vector<VPII>
#define VL vector<L>
#define VI vector<int>
#define VVI vector<VI>
#define VD vector<D>
#define VVD vector<VD>
#define VVPII vector<VPII>
#define VC vector<char>

using namespace std;

L a[1500][1500], res[1500][1500] = {0}, mx[1500][1500] = {0};

int main() {
    int n, m;
    sii(n, m);
    fin(i, n) { sal(a[i], m); }
    fin(i, n) {
        fin2(j, 1, m) {
            a[i][j] += a[i][j-1];
        }
    }
    fin(j, m) { res[0][j] = a[0][j]; }
    fin(i, n) {
        if (i % 2 == 0) {
            mx[i][m-1] = a[i][m-1];
            ford(j, m-1) {
                mx[i][j] = max(mx[i][j+1], a[i][j]);
            }
        }
        else {
            mx[i][0] = a[i][0];
            fin2(j, 1, m) {
                mx[i][j] = max(mx[i][j-1], a[i][j]);
            }
        }
    }
    fin(i, n) {
        fin(j, m) { res[i][j] = -pow(10, 18); }
    }
    //fin(i, n) { pal(a[i], m); }
    //fin(i, n) { pal(mx[i], m); }
    fin2(i, 1, n) {
        if (i % 2) {
            ford(j, m-1) {
                res[i][j] = max(res[i][j+1], a[i][j]+mx[i-1][j+1]);
            }
        }
        else {
            fin2(j, 1, m) {
                res[i][j] = max(res[i][j-1], a[i][j]+mx[i-1][j-1]);
            }
        }
    }
    if (n % 2 == 0) { pl(res[n-1][0]); }
    else { pl(res[n-1][m-1]); }
}


/* Worldwide Combos, free and competitive block-stacking game!
https://www.worldwide-combos.com */

#include<iostream>
#include<vector>
#include<array>
#include<string>
#include<sstream>
#include<map>
#include<unordered_map>
#include<chrono>
#include<set>
#include<unordered_set>
#include<ctime>
#include<bitset>
#include<queue>
#include<deque>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<random>
#include<cassert>
#include<complex>
#include<fstream>
#include<pthread.h>

#pragma GCC optimize "-O3"
#pragma GCC target "tune=native"

#define fin(i,n) for (int i = 0; i < n; i++)
#define fin2(i,a,b) for (int i = a; i < b; i++)
#define ford(i,n) for (int i = n-1; i >= 0; i--)
#define ford2(i,a,b) for (int i = b-1; i >= a; i--)

#define mp make_pair
#define mt make_tuple
#define pb push_back
#define mod 998244353
#define PI 3.1415926535897932384626
#define EXP1 2.718281828459045

#define si(n) scanf("%d", &n)
#define sii(n,m) scanf("%d %d", &n, &m)
#define siii(n,m,k) scanf("%d %d %d", &n, &m, &k)
#define sl(n) scanf("%lld", &n)
#define sll(n,m) scanf("%lld %lld", &n, &m)
#define slll(n,m,k) scanf("%lld %lld %lld", &n, &m, &k)
#define sd(n) scanf("%lf", &n)
#define sdd(n,m) scanf("%lf %lf", &n, &m)
#define sddd(n,m,k) scanf("%lf %lf %lf", &n, &m, &k)
#define sc(c) scanf("%c", &c)
#define ss(s) scanf("%s", s)
#define sai(t,n) fin(iz,n) { scanf("%d", &t[iz]); }
#define sal(t,n) fin(iz,n) { scanf("%lld", &t[iz]); }
#define sad(t,n) fin(iz,n) { scanf("%lf", &t[iz]); }

#define pc(n) printf("%c\n", n)
#define ps(s) printf("%s\n", s)
#define pi(n) printf("%d\n", n)
#define pii(n,m) printf("%d %d\n", n, m)
#define piii(n,m,k) printf("%d %d %d\n", n, m, k)
#define pl(n) printf("%lld\n", n)
#define pll(n,m) printf("%lld %lld\n", n, m)
#define plll(n,m,k) printf("%lld %lld %lld\n", n, m, k)
#define pd(n) printf("%lf\n", n)
#define pdd(n,m) printf("%lf %lf\n", n, m)
#define pai(t,n) fin(rz,n) { printf("%d ", t[rz]); } printf("\n")
#define pal(t,n) fin(rz,n) { printf("%lld ", t[rz]); } printf("\n")
#define pad(t,n) fin(rz,n) { printf("%lf ", t[rz]); } printf("\n")

#define OK ps("OK")
#define OK1 ps("OK1")
#define OK2 ps("OK2")

#define L long long int
#define D double
#define PII pair<int, int>
#define VPII vector<PII>
#define VVPII vector<VPII>
#define VL vector<L>
#define VI vector<int>
#define VVI vector<VI>
#define VD vector<D>
#define VVD vector<VD>
#define VVPII vector<VPII>
#define VC vector<char>

using namespace std;

L a[1500][1500], res[1500][1500] = {0}, mx[1500][1500] = {0};

int main() {
    int n, m;
    sii(n, m);
    fin(i, n) { sal(a[i], m); }
    fin(i, n) {
        fin2(j, 1, m) {
            a[i][j] += a[i][j-1];
        }
    }
    fin(j, m) { res[0][j] = a[0][j]; }
    fin(i, n) {
        if (i % 2 == 0) {
            mx[i][m-1] = a[i][m-1];
            ford(j, m-1) {
                mx[i][j] = max(mx[i][j+1], a[i][j]);
            }
        }
        else {
            mx[i][0] = a[i][0];
            fin2(j, 1, m) {
                mx[i][j] = max(mx[i][j-1], a[i][j]);
            }
        }
    }
    fin(i, n) {
        fin(j, m) { res[i][j] = -pow(10, 18); }
    }
    fin(j, m) { res[0][j] = mx[0][j]; }
    //pi(0);
    //pal(res[0], m);
    fin2(i, 1, n) {
        if (i % 2) {
            ford(j, m-1) {
                res[i][j] = a[i][j]+res[i-1][j+1];
            }
            //pi(i);
            //pal(res[i], m);
            fin2(j, 1, m) { res[i][j] = max(res[i][j-1], res[i][j]); }
        }
        else {
            fin2(j, 1, m) {
                res[i][j] = a[i][j]+res[i-1][j-1];
            }
            ford(j, m-1) { res[i][j] = max(res[i][j+1], res[i][j]); }
        }
        //pi(i);
        //pal(res[i], m);
    }
    //fin(i, n) { pal(res[i], m); }
    L r = 0;
    if (n % 2 == 0) {
        r = res[n-1][0];
        fin(i, m-1) { r = max(r, res[n-1][i]); }
    }
    else {
        r = res[n-1][1];
        fin2(i, 1, m) { r = max(r, res[n-1][i]); }
    }
    pl(r);
}


/* Worldwide Combos, free and competitive block-stacking game!
https://www.worldwide-combos.com */

#include<iostream>
#include<vector>
#include<array>
#include<string>
#include<sstream>
#include<map>
#include<unordered_map>
#include<chrono>
#include<set>
#include<unordered_set>
#include<ctime>
#include<bitset>
#include<queue>
#include<deque>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<stack>
#include<random>
#include<cassert>
#include<complex>
#include<fstream>
#include<pthread.h>

#pragma GCC optimize "-O3"
#pragma GCC target "tune=native"

#define fin(i,n) for (int i = 0; i < n; i++)
#define fin2(i,a,b) for (int i = a; i < b; i++)
#define ford(i,n) for (int i = n-1; i >= 0; i--)
#define ford2(i,a,b) for (int i = b-1; i >= a; i--)

#define mp make_pair
#define mt make_tuple
#define pb push_back
#define mod 998244353
#define PI 3.1415926535897932384626
#define EXP1 2.718281828459045

#define si(n) scanf("%d", &n)
#define sii(n,m) scanf("%d %d", &n, &m)
#define siii(n,m,k) scanf("%d %d %d", &n, &m, &k)
#define sl(n) scanf("%lld", &n)
#define sll(n,m) scanf("%lld %lld", &n, &m)
#define slll(n,m,k) scanf("%lld %lld %lld", &n, &m, &k)
#define sd(n) scanf("%lf", &n)
#define sdd(n,m) scanf("%lf %lf", &n, &m)
#define sddd(n,m,k) scanf("%lf %lf %lf", &n, &m, &k)
#define sc(c) scanf("%c", &c)
#define ss(s) scanf("%s", s)
#define sai(t,n) fin(iz,n) { scanf("%d", &t[iz]); }
#define sal(t,n) fin(iz,n) { scanf("%lld", &t[iz]); }
#define sad(t,n) fin(iz,n) { scanf("%lf", &t[iz]); }

#define pc(n) printf("%c\n", n)
#define ps(s) printf("%s\n", s)
#define pi(n) printf("%d\n", n)
#define pii(n,m) printf("%d %d\n", n, m)
#define piii(n,m,k) printf("%d %d %d\n", n, m, k)
#define pl(n) printf("%lld\n", n)
#define pll(n,m) printf("%lld %lld\n", n, m)
#define plll(n,m,k) printf("%lld %lld %lld\n", n, m, k)
#define pd(n) printf("%lf\n", n)
#define pdd(n,m) printf("%lf %lf\n", n, m)
#define pai(t,n) fin(rz,n) { printf("%d ", t[rz]); } printf("\n")
#define pal(t,n) fin(rz,n) { printf("%lld ", t[rz]); } printf("\n")
#define pad(t,n) fin(rz,n) { printf("%lf ", t[rz]); } printf("\n")

#define OK ps("OK")
#define OK1 ps("OK1")
#define OK2 ps("OK2")

#define L long long int
#define D double
#define PII pair<int, int>
#define VPII vector<PII>
#define VVPII vector<VPII>
#define VL vector<L>
#define VI vector<int>
#define VVI vector<VI>
#define VD vector<D>
#define VVD vector<VD>
#define VVPII vector<VPII>
#define VC vector<char>

using namespace std;

int a[1500][1500], res[1500][1500] = {0}, mx[1500][1500] = {0};

int main() {
    int n, m;
    sii(n, m);
    fin(i, n) { sai(a[i], m); }
    fin(i, n) {
        fin2(j, 1, m) {
            a[i][j] += a[i][j-1];
        }
    }
    fin(j, m) { res[0][j] = a[0][j]; }
    fin(i, n) {
        if (i % 2 == 0) {
            mx[i][m-1] = a[i][m-1];
            ford(j, m-1) {
                mx[i][j] = max(mx[i][j+1], a[i][j]);
            }
        }
        else {
            mx[i][0] = a[i][0];
            fin2(j, 1, m) {
                mx[i][j] = max(mx[i][j-1], a[i][j]);
            }
        }
    }
    fin2(i, 1, n) {
        if (i % 2) {
            ford(j, m-1) {
                res[i][j] = max(res[i][j+1], a[i][j]+mx[i-1][j]);
            }
        }
        else {
            fin2(j, 1, m) {
                res[i][j] = max(res[i][j-1], a[i][j]+mx[i-1][j]);
            }
        }
    }
    if (n % 2 == 0) { pi(res[n-1][0]); }
    else { pi(res[n-1][m-1]); }
}


#include<bits/stdc++.h>

using namespace std;

#define int long long
const int N=1505;

const int INF=1e15+6;

int dp[N][N],imax1[N][N],imax2[N][N],sum[N][N],a[N][N];
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    /*công thức dp của bài nay là
    nếu n lẻ thì dp[i][j]=max(imax1[i-1][j-1]+sum[i][j]);
    nếu n chẵn thì dp[i][j]=max(imax2[i-1][j+1]+sum[i][j]);
    Để tránh for thì imax1,và imax2 là màng dồn*/
    int n,m;

    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            if(j==1)sum[i][j]=a[i][j];
            else sum[i][j]=sum[i][j-1]+a[i][j];
        }
    }
    for(int i=0;i<=n+2;i++){
        for(int j=0;j<=m+2;j++){
            dp[i][j]=imax1[i][j]=imax2[i][j]=-INF;
        }
    }
    for(int i=m;i>=1;i--){
        dp[1][i]=sum[1][i];
        //cout<<dp[1][i]<<endl;
        if(i==m)imax1[1][m]=sum[1][m];
        else
        imax1[1][i]=max(dp[1][i],imax1[1][i+1]);
    }

    for(int i=2;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i%2==0){
                if(j==m)continue;
                dp[i][j]=max(dp[i][j],imax1[i-1][j+1]+sum[i][j]);
            }
            else{
                if(j==1)continue;
                dp[i][j]=max(dp[i][j],imax2[i-1][j-1]+sum[i][j]);
            }
            if(j==1)imax2[i][j]=dp[i][j];
            else imax2[i][j]=max(dp[i][j],imax2[i][j-1]);
        }
        for(int j=m;j>=1;j--){
            if(j==m)imax1[i][j]=dp[i][j];
            else imax1[i][j]=max(imax1[i][j+1],dp[i][j]);
        }
    }
    int ans=-INF;
    for(int i=1;i<=m;i++)ans=max(ans,dp[n][i]);
    cout<<ans;
}


#include <iostream>
#include <bits/stdc++.h>
#define maxN 1501
using namespace std;
/*int drvo[maxN][4*maxN];
int mat[maxN][maxN];
int str=1;
int findmax(int ind,int l,int r)
{
    l=l+str;
    r=r+str;
    int ans=INT_MIN;
    while(l<r)
    {
        if(l%2==1)
        {
            ans=max(ans,drvo[ind][l]);
            l++;
        }
        if(r%2==1)
        {
            r--;
            ans=max(ans,drvo[ind][r]);
        }
        l=l/2;
        r=r/2;
    }
    return ans;
}
void constr(int ind)
{
    for(int i=str-1;i>0;i--)
    {
        drvo[ind][i]=max(drvo[ind][2*i],drvo[ind][2*i+1]);
    }
}*/
int mat[maxN][maxN];
int dp[maxN][maxN];
int prefs[maxN][maxN];
int suf[maxN][maxN];
void constr(int ind,int n,int m)
{
    int maks=INT_MIN;
    for(int j=1;j<=m;j++)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        prefs[ind][j]=maks;
    }
    maks=INT_MIN;
    for(int j=m;j>=1;j--)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        suf[ind][j]=maks;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //ifstream cin("C:/Users/zoran/Desktop/drvo.txt");
    int n,m;
    cin>>n>>m;
   /* while(str<m)
    {
        str*=2;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>mat[i][j];
            if(j>0)
            {
                mat[i][j]+=mat[i][j-1];
            }
        }
    }
    for(int j=0;j<str;j++)
    {
        if(j<m)
        {
            drvo[1][str+j]=mat[1][j];
        }
        else{
            drvo[1][str+j]=INT_MIN;
        }
    }
    constr(1);
    for(int i=2;i<=n;i++)
    {
        if(i%2==0)
        {
            for(int j=0;j<str;j++)
            {
                if(j<m-1)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,j+1,m);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        else{
            for(int j=0;j<str;j++)
            {
                if(j>=1 && j<m)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,0,j);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        constr(i);
    }
    cout<<findmax(n,0,m);*/
   // cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>mat[i][j];
            mat[i][j]+=mat[i][j-1];
            dp[i][j]=mat[i][j];
        }
    }
    constr(1,n,m);
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i%2==0)
            {
                if(j<m)
                {
                    dp[i][j]=mat[i][j]+suf[i-1][j+1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
            else{
                if(j>1)
                {
                    dp[i][j]=mat[i][j]+prefs[i-1][j-1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
        }
        constr(i,n,m);
    }
    cout<<prefs[n][m];
    return 0;
}


#include <iostream>
#include <bits/stdc++.h>
#define maxN 1501
#define ll long long
#define llm LONG_LONG_MIN
using namespace std;
/*int drvo[maxN][4*maxN];
int mat[maxN][maxN];
int str=1;
int findmax(int ind,int l,int r)
{
    l=l+str;
    r=r+str;
    int ans=INT_MIN;
    while(l<r)
    {
        if(l%2==1)
        {
            ans=max(ans,drvo[ind][l]);
            l++;
        }
        if(r%2==1)
        {
            r--;
            ans=max(ans,drvo[ind][r]);
        }
        l=l/2;
        r=r/2;
    }
    return ans;
}
void constr(int ind)
{
    for(int i=str-1;i>0;i--)
    {
        drvo[ind][i]=max(drvo[ind][2*i],drvo[ind][2*i+1]);
    }
}*/
ll mat[maxN][maxN];
ll dp[maxN][maxN];
ll prefs[maxN][maxN];
ll suf[maxN][maxN];
void constr(int ind,int n,int m)
{
    ll maks=llm;
    for(int j=1;j<=m;j++)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        prefs[ind][j]=maks;
    }
    maks=llm;
    for(int j=m;j>=1;j--)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        suf[ind][j]=maks;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
   // ifstream cin("C:/Users/zoran/Desktop/drvo.txt");
    int n,m;
    cin>>n>>m;
   /* while(str<m)
    {
        str*=2;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>mat[i][j];
            if(j>0)
            {
                mat[i][j]+=mat[i][j-1];
            }
        }
    }
    for(int j=0;j<str;j++)
    {
        if(j<m)
        {
            drvo[1][str+j]=mat[1][j];
        }
        else{
            drvo[1][str+j]=INT_MIN;
        }
    }
    constr(1);
    for(int i=2;i<=n;i++)
    {
        if(i%2==0)
        {
            for(int j=0;j<str;j++)
            {
                if(j<m-1)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,j+1,m);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        else{
            for(int j=0;j<str;j++)
            {
                if(j>=1 && j<m)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,0,j);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        constr(i);
    }
    cout<<findmax(n,0,m);*/
   // cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>mat[i][j];
            mat[i][j]+=mat[i][j-1];
            dp[i][j]=mat[i][j];
        }
    }
    constr(1,n,m);
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i%2==0)
            {
                if(j<m)
                {
                    dp[i][j]=mat[i][j]+suf[i-1][j+1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
            else{
                if(j>1)
                {
                    dp[i][j]=mat[i][j]+prefs[i-1][j-1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
        }
        constr(i,n,m);
    }
    cout<<prefs[n][m];
    return 0;
}


#include <iostream>
#include <bits/stdc++.h>
#define maxN 1501
using namespace std;
/*int drvo[maxN][4*maxN];
int mat[maxN][maxN];
int str=1;
int findmax(int ind,int l,int r)
{
    l=l+str;
    r=r+str;
    int ans=INT_MIN;
    while(l<r)
    {
        if(l%2==1)
        {
            ans=max(ans,drvo[ind][l]);
            l++;
        }
        if(r%2==1)
        {
            r--;
            ans=max(ans,drvo[ind][r]);
        }
        l=l/2;
        r=r/2;
    }
    return ans;
}
void constr(int ind)
{
    for(int i=str-1;i>0;i--)
    {
        drvo[ind][i]=max(drvo[ind][2*i],drvo[ind][2*i+1]);
    }
}*/
int mat[maxN][maxN];
int dp[maxN][maxN];
int prefs[maxN][maxN];
int suf[maxN][maxN];
void constr(int ind,int n,int m)
{
    int maks=INT_MIN;
    for(int j=1;j<=n;j++)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        prefs[ind][j]=maks;
    }
    maks=INT_MIN;
    for(int j=n;j>=1;j--)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        suf[ind][j]=maks;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
   // ifstream cin("C:/Users/zoran/Desktop/drvo.txt");
    int n,m;
    cin>>n>>m;
   /* while(str<m)
    {
        str*=2;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>mat[i][j];
            if(j>0)
            {
                mat[i][j]+=mat[i][j-1];
            }
        }
    }
    for(int j=0;j<str;j++)
    {
        if(j<m)
        {
            drvo[1][str+j]=mat[1][j];
        }
        else{
            drvo[1][str+j]=INT_MIN;
        }
    }
    constr(1);
    for(int i=2;i<=n;i++)
    {
        if(i%2==0)
        {
            for(int j=0;j<str;j++)
            {
                if(j<m-1)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,j+1,m);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        else{
            for(int j=0;j<str;j++)
            {
                if(j>=1 && j<m)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,0,j);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        constr(i);
    }
    cout<<findmax(n,0,m);*/
   // cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>mat[i][j];
            mat[i][j]+=mat[i][j-1];
            dp[i][j]=mat[i][j];
        }
    }
    constr(1,n,m);
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i%2==0)
            {
                if(j<m)
                {
                    dp[i][j]=mat[i][j]+suf[i-1][j+1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
            else{
                if(j>1)
                {
                    dp[i][j]=mat[i][j]+prefs[i-1][j-1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
        }
        constr(i,n,m);
    }
    cout<<prefs[n][m];
    return 0;
}


#include <iostream>
#include <bits/stdc++.h>
#define maxN 1501
using namespace std;
/*int drvo[maxN][4*maxN];
int mat[maxN][maxN];
int str=1;
int findmax(int ind,int l,int r)
{
    l=l+str;
    r=r+str;
    int ans=INT_MIN;
    while(l<r)
    {
        if(l%2==1)
        {
            ans=max(ans,drvo[ind][l]);
            l++;
        }
        if(r%2==1)
        {
            r--;
            ans=max(ans,drvo[ind][r]);
        }
        l=l/2;
        r=r/2;
    }
    return ans;
}
void constr(int ind)
{
    for(int i=str-1;i>0;i--)
    {
        drvo[ind][i]=max(drvo[ind][2*i],drvo[ind][2*i+1]);
    }
}*/
int mat[maxN][maxN];
int dp[maxN][maxN];
int prefs[maxN][maxN];
int suf[maxN][maxN];
void constr(int ind,int n,int m)
{
    int maks=INT_MIN;
    for(int j=1;j<=m;j++)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        prefs[ind][j]=maks;
    }
    maks=INT_MIN;
    for(int j=m;j>=1;j--)
    {
        if(dp[ind][j]>maks)
        {
            maks=dp[ind][j];
        }
        suf[ind][j]=maks;
    }
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ifstream cin("C:/Users/zoran/Desktop/drvo.txt");
    int n,m;
    cin>>n>>m;
   /* while(str<m)
    {
        str*=2;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=0;j<m;j++)
        {
            cin>>mat[i][j];
            if(j>0)
            {
                mat[i][j]+=mat[i][j-1];
            }
        }
    }
    for(int j=0;j<str;j++)
    {
        if(j<m)
        {
            drvo[1][str+j]=mat[1][j];
        }
        else{
            drvo[1][str+j]=INT_MIN;
        }
    }
    constr(1);
    for(int i=2;i<=n;i++)
    {
        if(i%2==0)
        {
            for(int j=0;j<str;j++)
            {
                if(j<m-1)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,j+1,m);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        else{
            for(int j=0;j<str;j++)
            {
                if(j>=1 && j<m)
                {
                    drvo[i][j]=mat[i][j]+findmax(i-1,0,j);
                }
                else{
                    drvo[i][j]=INT_MIN;
                }
            }
        }
        constr(i);
    }
    cout<<findmax(n,0,m);*/
   // cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>mat[i][j];
            mat[i][j]+=mat[i][j-1];
            dp[i][j]=mat[i][j];
        }
    }
    constr(1,n,m);
    for(int i=2;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(i%2==0)
            {
                if(j<m)
                {
                    dp[i][j]=mat[i][j]+suf[i-1][j+1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
            else{
                if(j>1)
                {
                    dp[i][j]=mat[i][j]+prefs[i-1][j-1];
                }
                else{
                    dp[i][j]=INT_MIN;
                }
            }
        }
        constr(i,n,m);
    }
    cout<<prefs[n][m];
    return 0;
}


#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <bitset>
#include <queue>
#include <stack>
#include <sstream>
#include <cstring>
#include <numeric>
#include <ctime>
#include <iomanip>

#define y0 y3451
#define y1 y4562
#define j0 j25624
#define j1 j45624
#define re return
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int) (x).size())
#define rep(i, n) for (int i = 0; i < (n); i++)
#define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
#define sqr(x) ((x) * (x))
#define sqrt(x) sqrt(abs(x))
#define tr(x, y) ((x)*(x) + (y)*(y))

using namespace std;

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

const ld pi = 3.141592653589793238462643;

int n, m;
ll a[1510][1510];
ll s[1510][1510];
ll ma[1510][1510];
ll inf = 1000000000000000;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin >> n >> m;
    rep(i, n)
    {
        rep(j, m)
        {
            cin >> a[i][j];
        }
    }
    s[0][0] = a[0][0];
    for (int j = 1; j < m; j++)
    {
        s[0][j] = s[0][j-1] + a[0][j];
    }
    ma[0][m] = -inf;
    rrep(j, m)
    {
        ma[0][j] = max(s[0][j], ma[0][j+1]);
    }
    for (int i = 1; i < n; i++)
    {
        if (i % 2)
        {
            ll sc = 0;
            rep(j, m)
            {
                sc += a[i][j];
                if (j < m - 1) s[i][j] = sc + ma[i-1][j+1];
                else s[i][j] = -inf;
            }
            ma[i][0] = s[i][0];
            for (int j = 1; j < m; j++)
            {
                ma[i][j] = max(s[i][j], ma[i][j-1]);
            }
        }
        else
        {
            ll sc = 0;
            rep(j, m)
            {
                sc += a[i][j];
                if (j > 0) s[i][j] = sc + ma[i-1][j-1];
                else s[i][j] = -inf;
            }
            ma[i][m] = -inf;
            rrep(j, m)
            {
                ma[i][j] = max(s[i][j], ma[i][j+1]);
            }
        }
    }
    ll ans = -1000000000000000;
    rep(j, m) ans = max(ans, ma[n-1][j]);
    cout << ans;
    re 0;
}


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

ll a[3005];
//ll b[5005] , f[5005];

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

    //memset(a,0,sizeof(a));

    int n,m;
    cin >> n >> m;
    for(int i=0;i<n;i++)
    {
        vector<ll> g(3005,-30000009);
        //memset(g,-30000009,sizeof(g));

        if(i%2)
        {
            for(int j=m-2;j>=0;j--)
                g[j]=max(g[j+1],a[j+1]);
        }
        else
        {
            for(int j=1;j<m;j++)
                g[j]=max(g[j-1],a[j-1]);
        }

      //  for(int p=0;p<m;p++)
     //   cout<< g[p] << " ";
    //    cout << endl;

        ll sum=0;
        for(int j=0;j<m;j++)
        {
            int p;
            cin >> p;
            sum+=p;
            a[j]=g[j]+sum;
        //    cout << a[j] << "  " ;
        }
      //  cout << endl;
    }

    //for(int i=0;i<m;i++)
    //cout << a[i] << " ";
    cout << *max_element(a,a+m);
}


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

int a[3005];
//ll b[5005] , f[5005];

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

    //memset(a,0,sizeof(a));

    int n,m;
    cin >> n >> m;
    for(int i=0;i<n;i++)
    {
        vector<int> g(3005,-30000009);
        //memset(g,-30000009,sizeof(g));

        if(i%2)
        {
            for(int j=m-2;j>=0;j--)
                g[j]=max(g[j+1],a[j+1]);
        }
        else
        {
            for(int j=1;j<m;j++)
                g[j]=max(g[j-1],a[j-1]);
        }

      //  for(int p=0;p<m;p++)
     //   cout<< g[p] << " ";
    //    cout << endl;

        int sum=0;
        for(int j=0;j<m;j++)
        {
            int p;
            cin >> p;
            sum+=p;
            a[j]=g[j]+sum;
        //    cout << a[j] << "  " ;
        }
      //  cout << endl;
    }

    //for(int i=0;i<m;i++)
    //cout << a[i] << " ";
    cout << *max_element(a,a+m);
}


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

typedef long long ll;

int n, m;
vector<vector<ll> > arr, dp;

int main (int argc, char *argv[])
{
	scanf("%d%d", &n, &m);
	arr.resize(n);
	dp.resize(n);
	for(int i = 0; i < n; ++i) {
		arr[i].resize(m);
		dp[i].resize(m, -ll(1e18));
		for(int j = 0; j < m; ++j) {
			scanf("%lld", &arr[i][j]);
		}
	}
	ll cnt = 0;
	for(int j = 0; j < m; ++j) {
		cnt += arr[0][j];
		dp[0][j] = cnt;
	}
	for(int i = 1; i < n; ++i) {
		if(i % 2) {
			ll cnt = 0;
			vector<ll> new_dp;
			new_dp.resize(m);
			for(int j = m - 1; j >= 0; --j) {
				new_dp[j] = dp[i - 1][j];
				if(j != m - 1) {
					new_dp[j] = max(new_dp[j], new_dp[j + 1]);
				}
			}
			for(int j = 0; j + 1 < m; ++j) {
				cnt += arr[i][j];
				dp[i][j] = cnt + new_dp[j + 1];
			}
		} else {
			ll cnt = 0, mx = -ll(1e18);
			for(int j = 0; j < m; ++j) {
				cnt += arr[i][j];
				if(j) {
					dp[i][j] = cnt + mx;
				}
				mx = max(mx, dp[i - 1][j]);
			}
		}
	}
	ll ans = -ll(1e18);
	for(int j = 0; j < m; ++j) {
		ans = max(ans, dp[n - 1][j]);
	}
	printf("%lld", ans);

	return 0;
}


#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <unordered_map>
#include <set>
#include <string>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;

long long int a[2000][2000],sum[2000][2000],dp[2000][2000];

int main(){
	long long int i,j,t1,t2,t3,t4,n,m,ans,temp,maxi=1e15;
	scanf("%lld %lld",&n,&m);
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			scanf("%lld",&a[i][j]);
		}
	}
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			if(j==1){
				sum[i][j]=a[i][j];
				continue;
			}
			sum[i][j]=a[i][j]+sum[i][j-1];
		}
	}
	memset(dp,0,sizeof(dp));
	for(i=1;i<=m;i++){
		dp[1][i]=sum[1][i];
	}
	for(i=2;i<=n;i++){
		if(i&1){
			temp=-maxi;
			for(j=1;j<=m;j++){
				dp[i][j]=sum[i][j]+temp;
				temp=max(temp,dp[i-1][j]);
			}
		}
		else{
			temp=-maxi;
			for(j=m;j>=1;j--){
				dp[i][j]=sum[i][j]+temp;
				temp=max(temp,dp[i-1][j]);
			}
		}
	}
	ans=-maxi;
	for(i=1;i<=m;i++){
		ans=max(ans,dp[n][i]);
	}
	printf("%lld\n",ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <unordered_map>
#include <set>
#include <string>
#include <cmath>
#include <queue>
#include <stack>

using namespace std;

int a[2000][2000],sum[2000][2000],dp[2000][2000];

int main(){
	int i,j,t1,t2,t3,t4,n,m,ans,temp;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			scanf("%d",&a[i][j]);
		}
	}
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			if(j==1){
				sum[i][j]=a[i][j];
				continue;
			}
			sum[i][j]=a[i][j]+sum[i][j-1];
		}
	}
	memset(dp,0,sizeof(dp));
	for(i=1;i<=m;i++){
		dp[1][i]=sum[1][i];
	}
	for(i=2;i<=n;i++){
		if(i&1){
			temp=-1e9;
			for(j=1;j<=m;j++){
				dp[i][j]=sum[i][j]+temp;
				temp=max(temp,dp[i-1][j]);
			}
		}
		else{
			temp=-1e9;
			for(j=m;j>=1;j--){
				dp[i][j]=sum[i][j]+temp;
				temp=max(temp,dp[i-1][j]);
			}
		}
	}
	ans=-1e9;
	for(i=1;i<=m;i++){
		ans=max(ans,dp[n][i]);
	}
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define int long
const int N=1505;

const int INF=1e6+6;

int dp[N][N],imax1[N][N],imax2[N][N],sum[N][N],a[N][N];
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    /*công thức dp của bài nay là
    nếu n lẻ thì dp[i][j]=max(imax1[i-1][j-1]+sum[i][j]);
    nếu n chẵn thì dp[i][j]=max(imax2[i-1][j+1]+sum[i][j]);
    Để tránh for thì imax1,và imax2 là màng dồn*/
    int n,m;

    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>a[i][j];
            if(j==1)sum[i][j]=a[i][j];
            else sum[i][j]=sum[i][j-1]+a[i][j];
        }
    }
    for(int i=0;i<=n+2;i++){
        for(int j=0;j<=m+2;j++){
            dp[i][j]=imax1[i][j]=imax2[i][j]=-INF;
        }
    }
    for(int i=m;i>=1;i--){
        dp[1][i]=sum[1][i];
        //cout<<dp[1][i]<<endl;
        if(i==m)imax1[1][m]=sum[1][m];
        else
        imax1[1][i]=max(dp[1][i],imax1[1][i+1]);
    }

    for(int i=2;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(i%2==0){
                if(j==m)continue;
                dp[i][j]=max(dp[i][j],imax1[i-1][j+1]+sum[i][j]);
            }
            else{
                if(j==1)continue;
                dp[i][j]=max(dp[i][j],imax2[i-1][j-1]+sum[i][j]);
            }
            if(j==1)imax2[i][j]=dp[i][j];
            else imax2[i][j]=max(dp[i][j],imax2[i][j-1]);
        }
        for(int j=m;j>=1;j--){
            if(j==m)imax1[i][j]=dp[i][j];
            else imax1[i][j]=max(imax1[i][j+1],dp[i][j]);
        }
    }
    int ans=-INF;
    for(int i=1;i<=m;i++)ans=max(ans,dp[n][i]);
    cout<<ans;
}