#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <map> 
#include <string>
#include <vector>  
#include <iostream> 
#include <sstream> 
#include <queue>
#include <algorithm> 
#include <assert.h>
#include "dzialka.h"
#include "message.h"

using namespace std;
 
#define ll long long
#define PB 		push_back
#define FOR(a,start,end) 	for(int a=int(start); a<int(end); a++)
#define INF 		INT_MAX
#define SORT(a) 	sort(a.begin(),a.end()) 
#define CL(a,x) 		memset(a,x,sizeof(a))
#define REP(a,x)	for(int a=0;a<x;a++)
#define REP1(a,x)	for(int a=1;a<=x;a++)
#define MP 		make_pair

 
 
typedef vector<ll>     vi;
typedef pair<ll,ll>     pii; 
typedef vector<string> vs;
typedef vector<pii> vii;
typedef vector<vector<ll> > vvi;
typedef vector<vector<string> > vvs;
typedef vector<pair<string,string> > vss;
typedef pair<string,string> pss; 
typedef pair<ll,pii> ppii;
typedef vector<ppii> vppii;
typedef vector<vector<pii> > vvii;
typedef vector<vvi> vvvi;


ll nz,w,h;
ll m,n,k,z,a,b,c,d,z0;
vi vk;
vii vkx,vkx1;

ll dod(void){
	ll z=0ll;
	ll a,k,b;
//	for(int i=0;i<vkx.size();i++)
//		cerr<<vkx[i].first<<" "<<vkx[i].second<<endl;
	a=vkx.back().first;
	k=vkx.back().second;
	for(int i=vkx.size()-2;i>=0;i--){
		b=k-vkx[i].second;
		z+=a*b;
		a=vkx[i].first;
		k=vkx[i].second;
	}
	return z;
}
ll dod2(void){
	ll z=0ll;
	ll a1,a,k,b;
	int i,i1;

	a=vkx.back().first;
	k=vkx.back().second;
	a1=vkx1.back().first;
	i=vkx.size()-2;
	i1=vkx1.size()-2;
	while(i>=0&&i1>=0){
		
		if(vkx[i].second<vkx1[i1].second){
			b=k-vkx1[i1].second;
			z+=a*a1*b;
			a1=vkx1[i1].first;
			
			k=vkx1[i1].second;
			i1--;
		}
		else if(vkx[i].second>vkx1[i1].second){
			b=k-vkx[i].second;
			z+=a*a1*b;
			a=vkx[i].first;
			
			k=vkx[i].second;
			i--;
		}
		else {
			b=k-vkx[i].second;
			z+=a*a1*b;
			a=vkx[i].first;
			a1=vkx1[i1].first;
			
			k=vkx[i].second;
			i--;
			i1--;
		}
		/*
		if(m==4&&a*a1*b<0){
			cerr<<"vkx = ";
			for(int i=0;i<vkx.size();i++)
				cerr<<vkx[i].second<<" ";
			cerr<<endl;
			cerr<<"vkx1 = ";
			for(int i=0;i<vkx1.size();i++)
				cerr<<vkx1[i].second<<" ";
			cerr<<endl;
			cerr<<" blad dod2 "<<a<<" "<<a1<<" "<<b<<endl;
			while(1);
		}
		*/
	}
	return z;
}


int main() {  
	//freopen( "c:\\wojtek\\uva\\pa\\debug\\t1.in", "rt", stdin);  
	
	//pi=2*acos(0.0);
	 
	m=MyNodeId();
	nz=(ll)NumberOfNodes();
	
	w=GetFieldWidth();
	h=GetFieldHeight();
//	if(m==4){
//		cerr<<"m = "<<m<<" nz = "<<nz<<" w = "<<w<<" h = "<<h<<endl;
//	}
	if(h<500){
		if(m==0){
	//		cerr<<"m = "<<m<<" nz = "<<nz<<" w = "<<w<<" h = "<<h<<endl;
			vk.assign(w,0ll);
			
			z=0ll;
			for(int i=0;i<h;i++){
				vkx.clear();
				vkx.push_back(MP(0ll,-1ll));
				for(int j=0;j<w;j++){
					if(IsUsableCell(i,j)){
						vk[j]++;
				//		cerr<<" i, j,vk[j] "<<i<<" "<<j<<" "<<vk[j]<<endl;
						for(int jx=vkx.size()-1;jx>0;jx--){
							if(vkx[jx].first>=vk[j])
								vkx.pop_back();
							else
								break;
						}
						vkx.push_back(MP(vk[j],j));
						z+=dod();
				//		cerr<<z<<endl;
					}
					else {
						vkx.clear();
						vkx.push_back(MP(0ll,j));
						vk[j]=0;
					}
				}
			//	for(int ix=0;ix<w;ix++)
			//		cerr<<vk[ix]<<" ";
			//	cerr<<endl;
			}

			cout<<z<<endl;
		}
	}
	else {
		k=h/nz;    //ile wierszy w każdej instancji

		int k1=m*k;
		int k2=(m+1)*k-1;
		if(m==nz-1)
			k2=h-1;
	//	if(m==4)
	//		cerr<<"k = "<<k<<" k1 = "<<k1<<" k2 = "<<k2<<endl;
		//
		vk.assign(w,0ll);
		
		z=0ll;
		for(int i=k1;i<=k2;i++){
			vkx.clear();
			vkx.push_back(MP(0ll,-1ll));
			for(int j=0;j<w;j++){
				if(IsUsableCell(i,j)){
					vk[j]++;
					for(int jx=vkx.size()-1;jx>0;jx--){
						if(vkx[jx].first>=vk[j])
							vkx.pop_back();
						else
							break;
					}
					vkx.push_back(MP(vk[j],j));
					z+=dod();
				}
				else {
					vkx.clear();
					vkx.push_back(MP(0ll,j));
					vk[j]=0;
				}
			}
		}
		
	//	if(m==4)
	//		cerr<<"z = "<<z<<endl;
	
		if(m>0){
			vi vk1;
			vk1.assign(w,0ll);
			for(int j=0;j<w;j++){
				int i=k1;
				ll a=0;
				while(i<=k2&&IsUsableCell(i,j)){
					a++;
					i++;
				}
				vk1[j]=a;
			}
		//	Receive(m-1);
		//	ll z0=GetLL(m-1);
		//	z+=z0;
			vi vk0;
			vk0.assign(w,0ll);
		//	cerr<<"node "<<m<<" received "<<z0<<" from node "<<m-1<<endl;

			ll i=0;
			ll imax=15000ll;
			while(i<w){


				Receive(m-1);
				for(;i<min(imax,w);i++){
					vk0[i]=GetInt(m-1);
				}
				imax+=15000ll;
			}
			
			//mamy vk1 i vk0;
			vkx.clear();
			vkx.push_back(MP(0ll,-1ll));
			vkx1.clear();
			vkx1.push_back(MP(0ll,-1ll));
			//
			for(int j=0;j<w;j++){
				if((vk0[j]!=0)&&(vk1[j]!=0)){
					
					for(int jx=vkx.size()-1;jx>0;jx--){
						if(vkx[jx].first>=vk0[j])
							vkx.pop_back();
						else
							break;
					}
					vkx.push_back(MP(vk0[j],j));
					for(int jx=vkx1.size()-1;jx>0;jx--){
						if(vkx1[jx].first>=vk1[j])
							vkx1.pop_back();
						else
							break;
					}
					vkx1.push_back(MP(vk1[j],j));
			//		if(m==4&&vkx1.back().second!=vkx.back().second)
			//			cerr<<"blad "<<vkx1.back().second<<" "<<vkx.back().second<<endl;
					z+=dod2();
				}
				else {
			//	if((vk0[j]==0)||(vk1[j]==0)){
					vkx.clear();
					vkx.push_back(MP(0ll,j));
			//	}
			//	if(vk1[j]==0){
					vkx1.clear();
					vkx1.push_back(MP(0ll,j));
				}

				if(vk[j]==k2-k1+1)
					vk[j]+=vk0[j];
			}
			//
			Receive(m-1);
			z0=GetLL(m-1);
		//	if(m==4)
		//		cerr<<"node "<<m<<" received "<<z0<<" from node "<<m-1<<endl;
			z+=z0;
		//	if(m==4)
		//		cerr<<" z2 = "<<z<<endl;

		}
		if(m<nz-1){
			
			ll i=0;
			ll imax=15000ll;
			while(i<w){

				for(;i<min(imax,w);i++){
					PutInt(m+1,vk[i]);
				}
				Send(m+1);
				imax+=15000ll;
				
			}
		
			PutLL(m+1,z);
		//	if(m<5)
		//		cerr<<"node "<<m<<" sent "<<z<<" to node "<<m+1<<endl;
		//	if(m==98)
		//		cerr<<"node "<<m<<" sent "<<z<<" to node "<<m+1<<endl;
			Send(m+1);

		}
		else {
			cout<<z<<endl;
		}


		
	}
	




	
	//czas = clock() - czas;
	//printf("%lf\n",double(czas)/CLOCKS_PER_SEC);					
//}
			
	return 0;
	 
} 
