def input_s():
    return raw_input()

def input_i():
    return int(raw_input())

def input_2_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1]

def input_3_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1], arr[2]

def input_i_array():
    return map(int, raw_input().split())

def get_presum(n, arr):
    presum = [arr[0]]
    for i in range(1, n):
        presum.append(presum[i - 1] + arr[i])
    return presum

def calc(n, a):
    dp = [[0, 0] for _ in range(n)]
    remain = [[0, 0] for _ in range(n)]
    dp[0] = [0, a[0] / 3]
    remain[0] = [a[0], a[0] % 3]
    for i in range(1, n):
        dp[i][0] = max(dp[i - 1])
        if dp[i - 1][0] > dp[i - 1][1]:
            remain[i][0] = remain[i - 1][0] + a[i]
        elif dp[i - 1][0] < dp[i - 1][1]:
            remain[i][0] = remain[i - 1][1] + a[i]
        else:
            remain[i][0] = max(remain[i - 1])

        cnt_cost = [
            min(a[i] / 2, remain[i - 1][0]),
            min(a[i] / 2, remain[i - 1][1])
        ]

        extras = [
            (a[i] - cnt_cost[0] * 2) / 3,
            (a[i] - cnt_cost[1] * 2) / 3
        ]

        if cnt_cost[0] + extras[0] > cnt_cost[1] + extras[1]:
            dp[i][1] = dp[i - 1][0] + cnt_cost[0] + extras[0]
            remain[i][1] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2 - extras[0] * 3)
        elif cnt_cost[0] + extras[0] < cnt_cost[1] + extras[1]:
            dp[i][1] = dp[i - 1][1] + cnt_cost[1] + extras[1]
            remain[i][1] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2 - extras[1] * 3)
        else:
            if dp[i - 1][0] > dp[i - 1][1]:
                dp[i][1] = dp[i - 1][0] + cnt_cost[0] + extras[0]
                remain[i][1] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2 - extras[0] * 3)
            elif dp[i - 1][0] < dp[i - 1][1]:
                dp[i][1] = dp[i - 1][1] + cnt_cost[1] + extras[1]
                remain[i][1] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2 - extras[1] * 3)
            else:
                dp[i][1] = dp[i - 1][1] + cnt_cost[1] + extras[1]
                if remain[i - 1][0] > remain[i - 1][1]:
                    remain[i][1] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2 - extras[0] * 3)
                else:
                    remain[i][1] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2 - extras[1] * 3)

    """
    for i in range(n):
        print '{}({}) '.format(dp[i][0], remain[i][0]),

    print ''

    for i in range(n):
        print '{}({}) '.format(dp[i][1], remain[i][1]),

    print ''
    """
    return max(dp[n - 1])

"""
5
1 3 3 5 3
"""

n = input_i()
arr = input_i_array()

print calc(n, arr)


def input_s():
    return raw_input()

def input_i():
    return int(raw_input())

def input_2_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1]

def input_3_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1], arr[2]

def input_i_array():
    return map(int, raw_input().split())

def get_presum(n, arr):
    presum = [arr[0]]
    for i in range(1, n):
        presum.append(presum[i - 1] + arr[i])
    return presum

def calc(n, a):
    dp = [[0, 0] for _ in range(n)]
    remain = [[0, 0] for _ in range(n)]
    dp[0] = [0, a[0] / 3]
    remain[0] = [a[0], a[0] % 3]
    for i in range(1, n):
        cnt_cost = [
            min(remain[i - 1][0], a[i] / 2),
            min(remain[i - 1][1], a[i] / 2)
        ]
        cnt_dp = [
            dp[i - 1][0] + cnt_cost[0],
            dp[i - 1][1] + cnt_cost[1]
        ]

        if cnt_dp[0] > cnt_dp[1]:
            dp[i][0] = cnt_dp[0]
            remain[i][0] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2)
        elif cnt_dp[0] < cnt_dp[1]:
            dp[i][0] = cnt_dp[1]
            remain[i][0] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2)
        else:
            dp[i][0] = cnt_dp[1]
            remain[i][0] = max(
                remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2),
                remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2)
            )

        cnt_remain = a[i] % 3
        dp[i][1] = max(dp[i - 1]) + a[i] / 3
        if a[i] % 3 == 2 and max(remain[i - 1]) >= 1:
            dp[i][1] += 1
            cnt_remain = -1

        if dp[i - 1][1] > dp[i - 1][0] or dp[i - 1][1] == dp[i - 1][0] and remain[i - 1][1] > remain[i - 1][0]:
            cnt_remain += remain[i - 1][1]
        else:
            cnt_remain += remain[i - 1][0]

        remain[i][1] = cnt_remain
    """
    for i in range(n):
        print '{}({}) '.format(dp[i][0], remain[i][0]),

    print ''

    for i in range(n):
        print '{}({}) '.format(dp[i][1], remain[i][1]),

    print ''
    """
    return max(dp[n - 1])

"""
5
1 3 3 5 3
"""

n = input_i()
arr = input_i_array()

print calc(n, arr)


def input_s():
    return raw_input()

def input_i():
    return int(raw_input())

def input_2_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1]

def input_3_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1], arr[2]

def input_i_array():
    return map(int, raw_input().split())

def get_presum(n, arr):
    presum = [arr[0]]
    for i in range(1, n):
        presum.append(presum[i - 1] + arr[i])
    return presum

def calc(n, a):
    dp = [[0, 0] for _ in range(n)]
    remain = [[0, 0] for _ in range(n)]
    dp[0] = [0, a[0] / 3]
    remain[0] = [a[0], a[0] % 3]
    for i in range(1, n):
        cnt_cost = [
            min(remain[i - 1][0], a[i] / 2),
            min(remain[i - 1][1], a[i] / 2)
        ]
        cnt_dp = [
            dp[i - 1][0] + cnt_cost[0],
            dp[i - 1][1] + cnt_cost[1]
        ]

        if cnt_dp[0] > cnt_dp[1]:
            dp[i][0] = cnt_dp[0]
            remain[i][0] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2)
        else:
            dp[i][0] = cnt_dp[1]
            remain[i][0] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2)

        dp[i][1] = max(dp[i - 1]) + a[i] / 3

        pre_remain = remain[i - 1][0]
        if dp[i - 1][1] > dp[i - 1][0] or dp[i - 1][1] == dp[i - 1][0] and remain[i - 1][1] > remain[i - 1][0]:
            pre_remain = remain[i - 1][1]

        remain[i][1] = a[i] % 3 + pre_remain

        # print 'dp[{}] = {}'.format(i, remain[i])

    return max(dp[n - 1])

"""
5
1 2 2 2 2
"""

n = input_i()
arr = input_i_array()

print calc(n, arr)


def input_s():
    return raw_input()

def input_i():
    return int(raw_input())

def input_2_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1]

def input_3_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1], arr[2]

def input_i_array():
    return map(int, raw_input().split())

def get_presum(n, arr):
    presum = [arr[0]]
    for i in range(1, n):
        presum.append(presum[i - 1] + arr[i])
    return presum

def calc(n, a):
    dp = [[0, 0] for _ in range(n)]
    remain = [[0, 0] for _ in range(n)]
    dp[0] = [0, a[0] / 3]
    remain[0] = [a[0], a[0] % 3]
    for i in range(1, n):
        cnt_cost = [
            min(remain[i - 1][0], a[i] / 2),
            min(remain[i - 1][1], a[i] / 2)
        ]
        cnt_dp = [
            dp[i - 1][0] + cnt_cost[0],
            dp[i - 1][1] + cnt_cost[1]
        ]

        if cnt_dp[0] > cnt_dp[1]:
            dp[i][0] = cnt_dp[0]
            remain[i][0] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2)
        elif cnt_dp[0] < cnt_dp[1]:
            dp[i][0] = cnt_dp[1]
            remain[i][0] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2)
        else:
            dp[i][0] = cnt_dp[1]
            remain[i][0] = max(
                remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2),
                remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2)
            )

        dp[i][1] = max(dp[i - 1]) + a[i] / 3

        pre_remain = remain[i - 1][0]
        if dp[i - 1][1] > dp[i - 1][0] or dp[i - 1][1] == dp[i - 1][0] and remain[i - 1][1] > remain[i - 1][0]:
            pre_remain = remain[i - 1][1]

        remain[i][1] = a[i] % 3 + pre_remain

        # print 'dp[{}] = {}'.format(i, remain[i])

    return max(dp[n - 1])

"""
5
1 2 2 2 2
"""

n = input_i()
arr = input_i_array()

print calc(n, arr)


def input_s():
    return raw_input()

def input_i():
    return int(raw_input())

def input_2_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1]

def input_3_i():
    arr = map(int, raw_input().split())
    return arr[0], arr[1], arr[2]

def input_i_array():
    return map(int, raw_input().split())

def get_presum(n, arr):
    presum = [arr[0]]
    for i in range(1, n):
        presum.append(presum[i - 1] + arr[i])
    return presum

def calc(n, a):
    dp = [[0, 0] for _ in range(n)]
    remain = [[0, 0] for _ in range(n)]
    dp[0] = [0, a[0] / 3]
    remain[0] = [a[0], a[0] % 3]
    for i in range(1, n):
        dp[i][0] = max(dp[i - 1])
        if dp[i - 1][0] > dp[i - 1][1]:
            remain[i][0] = remain[i - 1][0] + a[i]
        elif dp[i - 1][0] < dp[i - 1][1]:
            remain[i][0] = remain[i - 1][1] + a[i]
        else:
            remain[i][0] = max(remain[i - 1]) + a[i]

        cnt_cost = [
            min(a[i] / 2, remain[i - 1][0]),
            min(a[i] / 2, remain[i - 1][1])
        ]

        extras = [
            (a[i] - cnt_cost[0] * 2) / 3,
            (a[i] - cnt_cost[1] * 2) / 3
        ]

        if cnt_cost[0] + extras[0] > cnt_cost[1] + extras[1]:
            dp[i][1] = dp[i - 1][0] + cnt_cost[0] + extras[0]
            remain[i][1] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2 - extras[0] * 3)
        elif cnt_cost[0] + extras[0] < cnt_cost[1] + extras[1]:
            dp[i][1] = dp[i - 1][1] + cnt_cost[1] + extras[1]
            remain[i][1] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2 - extras[1] * 3)
        else:
            if dp[i - 1][0] > dp[i - 1][1]:
                dp[i][1] = dp[i - 1][0] + cnt_cost[0] + extras[0]
                remain[i][1] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2 - extras[0] * 3)
            elif dp[i - 1][0] < dp[i - 1][1]:
                dp[i][1] = dp[i - 1][1] + cnt_cost[1] + extras[1]
                remain[i][1] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2 - extras[1] * 3)
            else:
                dp[i][1] = dp[i - 1][1] + cnt_cost[1] + extras[1]
                if remain[i - 1][0] > remain[i - 1][1]:
                    remain[i][1] = remain[i - 1][0] - cnt_cost[0] + (a[i] - cnt_cost[0] * 2 - extras[0] * 3)
                else:
                    remain[i][1] = remain[i - 1][1] - cnt_cost[1] + (a[i] - cnt_cost[1] * 2 - extras[1] * 3)

    """
    for i in range(n):
        print '{}({}) '.format(dp[i][0], remain[i][0]),

    print ''

    for i in range(n):
        print '{}({}) '.format(dp[i][1], remain[i][1]),

    print ''
    """
    return max(dp[n - 1])

"""
5
1 3 3 5 3
"""

n = input_i()
arr = input_i_array()

print calc(n, arr)


#include<stdio.h>
#define ll long long
int main()
{
	long long int n;
	scanf("%lld",&n);
	ll cnt=0,cnt1=0,temp;
	for(int i=0;i<n;i++)
	{
		scanf("%lld",&temp);
		if(temp==1)
			cnt1++;
		else if(temp==2)
		{
			if(cnt1>0)
			{
				cnt1--;
				cnt++;
			}
			else
				cnt1+=2;
		}
		else
		{
			while(temp>=2&&cnt1)
			{
				cnt++;
				cnt1--;
				temp-=2;
			}
			cnt+=temp/3;
			cnt1+=temp%3;
		}
	}
	printf("%lld",cnt);
	return 0;
}


#include<stdio.h>
#define ll long long
int main()
{
	ll n;
	scanf("%lld",&n);
	ll cnt=0,cnt1=0,cnt2=0;
	for(int i=0;i<n;i++)
	{
		ll temp;
		scanf("%lld",&temp);
		if(temp>=3)
		{
			cnt+=temp/3;
			if(temp%3==2)
			{
				if(cnt2>0)
				{
					cnt++;
					cnt2--;
					cnt1++;
				}
				else if(cnt1>0)
				{
					cnt++;
					cnt1--;
				}
				else
				{
					cnt2++;
				}
			}
			else if(temp%3==1)
			{
				cnt1++;
			}
		}
		else if(temp==2)
		{
			if(cnt2>0)
			{
				cnt++;
				cnt1++;
				cnt2--;
			}
			else if(cnt1>0)
			{
				cnt++;
				cnt1--;
			}
			else
				cnt2++;
		}
		else
			cnt1++;

	}
	printf("%lld",cnt);
	return 0;
}


#include<stdio.h>

int main(void){

	unsigned long n,p,g=0;int count=0;
	scanf("%lu\n",&n);
	while(n>0){

		scanf("%lu",&p);
		while(p>1){

			if(count!=0){

				count--;
				g++;
				p=p-2;
			}
			else{

				g=g+p/3;
				if((p%3)==1)
					count++;
				else if((p%3)==2)
					count=count+2;
				p=0;

			}

		}
		if((p==1) && (n!=1))
			count++;

		n--;
	}
	printf("%lu\n",g);

	return 0;
}


#include<stdio.h>

int main(void){

	unsigned long n,p;unsigned long long g=0;int count=0;
	scanf("%lu\n",&n);
	while(n>0){

		scanf("%lu",&p);
		while(p>1){

			if(count!=0){

				count--;
				g++;
				p=p-2;
			}
			else{

				g=g+p/3;
				if((p%3)==1)
					count++;
				else if((p%3)==2)
					count=count+2;
				p=0;

			}

		}
		if((p==1) && (n!=1))
			count++;

		n--;
	}
	printf("%I64u\n",g);

	return 0;
}


#include <stdio.h>
int main ()
{
    long long int n;
    scanf("%lld", &n);
    long long int a[n],x1=0,x2=0,c=0;
    for (int i=0;i<n;i++)
    {
        scanf("%lld", &a[i]);
        x1=x1+a[i]%2;
        x2=x2+a[i]/2;
    }
    if (x1>x2)
    c=c+x2;
    if (x1==x2)
    c=c+x1;
    if (x1<x2)
    {
        c=c+x1;
        x2-=x1;
        c=c+((2*x2)/3);
    }
    printf("%lld", c);
    return 0;
}


#include<stdio.h>
int main()
{
    long long int n,basket=0,c=0,pair,a;
	scanf("%lld", &n);
	for(int i=1;i<=n;i++)
	{
	    scanf("%lld", &a);
	    pair=a/2;
		if (basket<(a/2))
		pair=basket;
		basket-=pair;
		a-=2*pair;
		c+=pair+a/3;
		basket+=a%3;
	}
	printf("%lld", c);
	return 0;
}


#include <stdio.h>
int main ()
{
    long long int n;
    scanf("%lld", &n);
    long long int a[n],x1=0,x2=0,c=0,s=0;
    for (int i=0;i<n;i++)
    {
        scanf("%lld", &a[i]);
    }
    for (int i=0;i<n;i++)
    {
        for (int j=(i+1);j<n;j++)
        {
            while (a[i]>0&&a[j]>0)
            {
                a[i]-=1;
                a[j]-=2;
                c++;
            }
        }
        s=s+a[i];
    }

    printf("%lld", (c+s/3));
    return 0;
}


    #include<stdio.h>

    int main()
    {

    	 long long N, count=0;
    	long long int carry=0;
    	scanf("%lli", &N);
            long long int curr;
    	while (N>0)
    	{
    		scanf("%lli", &curr);

    		while (carry>0 && curr>1)
    	       	{
    		        carry--;
    			curr=curr-2;
    			count++;
    		}

    		count=count+(curr/3);
    		carry=carry+(curr%3);
    		N--;
    	}

    	printf("%lli", count);

    	return 0;
    }


#include<stdio.h>

int main()
{

	unsigned long long N, count=0;
	long long int carry=0;
	scanf("%I64u", &N);
        long long int curr;
	while (N>0)
	{
		scanf("%I64d", &curr);

		while (carry>0 && curr>1)
	       	{
		        carry--;
			curr=curr-2;
			count++;
		}

		count=count+(curr/3);
		carry=curr%3;
		N--;
	}

	printf("%I64u", count);

	return 0;
}


#include<stdio.h>

int main()
{

	unsigned long long N, count=0;
	long long int carry=0;
	scanf("%I64u", &N);
        long long int curr;
	while (N>0)
	{
		scanf("%I64d", &curr);

		while (carry>0 && curr>1)
	       	{
		        carry--;
			curr=curr-2;
			count++;
		}

		count=count+(curr/3);
		carry=carry+(curr%3);
		N--;
	}

	printf("%I64u", count);

	return 0;
}


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

typedef int64_t i64;
typedef int32_t i32;

static void print_int(i64 n){if(n<0){putchar('-');n=-n;}if(n==0){putchar('0');return;}int s[20],len=0;while(n>0){s[len++]=n%10+'0';n/=10;}while(len>0){putchar(s[--len]);}}
static i64 read_int(void){int prev='\0';int c=getchar();while(!('0'<=c && c<='9')){prev=c;c=getchar();}i64 res=0;while('0'<=c && c<='9'){res=10*res+c-'0';c=getchar();}return prev=='-'?-res:res;}

void run (void) {
  const i32 n = read_int();
  i32 *a = (i32 *) calloc (n, sizeof (i32));
  for (i32 i = 0; i < n; ++i) {
    a[i] = read_int();
  }
  i64 ans = 0;
  i64 remain = 0;
  for (i32 i = 0; i < n; ++i) {
    while (remain > 0 && a[i] >= 2) {
      ans++;
      remain--;
      a[i] -= 2;
    }
    ans += a[i] / 3;
    remain += a[i] % 3;
  }
  print_int (ans);
  puts("");
}

int main (void) {
  run ();
  return 0;
}


#include<stdio.h>
long long n,a[300000],l=0,mg=0;
int main()
{

	scanf("%lld",&n);
	for(long long i=0;i<n;i++)
	{
		scanf("%lld",&a[i]);
	}

	for(long long i =0;i<n;i++)
	{

	  if (l<=a[i]/2)
		{
			 mg+=l;
	        	 a[i]=a[i]-2*l;
                         l=0;

		}
	  else
		 {
	 		mg+=a[i]/2;
			l=l-a[i]/2;
		 }
	  mg+=a[i]/3;
	  a[i]%=3;
	  l+=a[i];

	}
       printf("%lld\n", mg);
	return 0;
}


#include<stdio.h>
long long n,a[100000],l=0,mg=0;
int main()
{
	freopen("testcase.txt", "r", stdin);-
	scanf("%lld",&n);
	for(long long i=0;i<n;i++)
	{
		scanf("%lld",&a[i]);
	}

	for(long long i =0;i<n;i++)
	{

	  if (l<=a[i]/2)
		{
			 mg+=l;
	        	 a[i]=a[i]-2*l;
                         l=0;

		}
	  else
		 {
	 		mg+=a[i]/2;
			l=l-a[i]/2;
			a[i]=a[i]%2;
			l+=a[i];
		 }
	  mg+=a[i]/3;
	  a[i]%=3;
	  l+=a[i];

	}
       printf("%lld\n", mg);
	return 0;
}


#include<stdio.h>
#define ll long long

ll min(ll a, ll b)
{
	return a<b?a:b;
}

int main()
{

	ll mi,n,a,one=0,set=0;
	scanf("%lld",&n);
//n=300000;
	for(ll i=0; i<n; i++)
	{
		scanf("%lld",&a);
		// a=1000000000;

		mi= min(one,a/2);
		set+= mi; one-= mi; a-= 2*mi;

		set+= a/3;
		a= a%3;

		one+=a;
	}
	printf("%lld\n",set);

	return 0;
}


#include<stdio.h>
#define ll long long

ll min(ll a, ll b)
{
	ll c=a<b?a:b;
	return c;
}

int main()
{

	ll mi,n,a,one=0,set=0;
	scanf("%lld",&n);
	for(ll i=0;i<n;i++)
	{
		scanf("%lld",&a);

		mi= min(one,a/2);
		set+= mi; one-= mi; a-= 2*mi;

		set+=a/3;
		a-=a/3;

		one+=a;
	}
	printf("%lld\n",set);

	return 0;
}


#include<stdio.h>

int min(int a, int b)
{
	int c=a<b?a:b;
	return c;
}

int main()
{

	int mi,n,a,one=0,set=0;
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",&a);

		mi= min(one,a/2);
		set+= mi; one-= mi; a-= 2*mi;

		set+=a/3;
		a-=a/3;

		one+=a;
	}
	printf("%d\n",set);

	return 0;
}


#include<stdio.h>
#define ll long long
long long arr[200005];
#define min(a,b) (a>b)?b:a
int n;
long long solve()
{
	// for(int i=0;i<n;i++)
		// printf("%lld ",arr[i]);
	long long c2=0,c4=0;
	long long ans=0;
	for(long long i=0;i<n;i++)
	{
		if(arr[i]==0 || arr[i]==1)
			continue;
		long long p1=arr[i]%3;
		if(p1==1)
		{
			ans+=((arr[i]-4)/3);
			arr[i]=4;
		}
		else if(p1==2)
		{
			ans+=((arr[i]-2)/3);
			arr[i]=2;
		}
		else
		{
			ans+=(arr[i]/3);
			arr[i]=0;
		}

	}
	// for(int i=0;i<n;i++)/
		// printf("%lld ",arr[i]);
	for(long long i=0;i<n;i++)
	{
		if(arr[i]==2)
			c2++;
		else if(arr[i]==4)
		{
			c4++;
		}

	}
	// printf("\n%lld\n",min(c2,c4));
	ll mn=min(c2,c4);
	ans+=(mn*2);
	// printf("ans= %lld\n",ans);
	if(c2 < c4)
	{
		ans+=(((c4-c2)*4)/3);
	}
	else
	{
		ans+=(((c2-c4)*2)/3);
	}
	return ans;
}
int main()
{
	long long ans=0;
	scanf("%d",&n);
	for(long long i=0;i<n;i++)
		scanf("%lld",&arr[i]);
	long long c=1,p1=0;
	while(p1 < n && arr[p1]!=1)
		p1++;
	if(p1==n)
	{
		ans+=solve();
	}
	else
	{
		for(long long i=p1+1;i<n;i++)
		{
			if(arr[i]!=1)
			{

				long long pr=min((arr[i]/2),c);
				arr[i]-=2*pr;
				ans+=pr;
				c-=pr;
				if(arr[i]==1)
					c++;
			}
			else
				c++;
		}
		ans+=solve();
	}
	printf("%lld\n",ans);
  return 0;
}


#include<stdio.h>
#define ll long long
long long arr[300005];
#define min(a,b) (a>b)?b:a
int n;
long long solve()
{
	// for(int i=0;i<n;i++)
		// printf("%lld ",arr[i]);
	long long c2=0,c4=0;
	long long ans=0;
	for(long long i=0;i<n;i++)
	{
		if(arr[i]==0 || arr[i]==1)
			continue;
		long long p1=arr[i]%3;
		if(p1==1)
		{
			ans+=((arr[i]-4)/3);
			arr[i]=4;
		}
		else if(p1==2)
		{
			ans+=((arr[i]-2)/3);
			arr[i]=2;
		}
		else
		{
			ans+=(arr[i]/3);
			arr[i]=0;
		}

	}
	// for(int i=0;i<n;i++)/
		// printf("%lld ",arr[i]);
	for(long long i=0;i<n;i++)
	{
		if(arr[i]==2)
			c2++;
		else if(arr[i]==4)
		{
			c4++;
		}

	}
	// printf("\n%lld\n",min(c2,c4));
	ll mn=min(c2,c4);
	ans+=(mn*2);
	// printf("ans= %lld\n",ans);
	if(c2 < c4)
	{
		ans+=(((c4-c2)*4)/3);
	}
	else
	{
		ans+=(((c2-c4)*2)/3);
	}
	return ans;
}
int main()
{
	long long ans=0;
	scanf("%d",&n);
	for(long long i=0;i<n;i++)
		scanf("%lld",&arr[i]);
	long long c=1,p1=0;
	while(p1 < n && arr[p1]!=1)
		p1++;
	if(p1==n)
	{
		ans+=solve();
	}
	else
	{
		for(long long i=p1+1;i<n;i++)
		{
			if(arr[i]!=1)
			{

				long long pr=min((arr[i]/2),c);
				arr[i]-=2*pr;
				ans+=pr;
				c-=pr;
				if(arr[i]==1)
					c++;
			}
			else
				c++;
		}
		ans+=solve();
	}
	printf("%lld\n",ans);
  return 0;
}


#include<stdio.h>

int main()
{
    long long int N,i, gr=0, rem=0;
    scanf("%lld", &N);
    long long int ar[N];
    for(i=0;i<N;i++)
    {
        scanf("%lld", &ar[i]);
    }
    for(i=0;i<N;i++)
    {
        if(ar[i]>=2)
        {
            if(rem==0)
            {
                gr+=ar[i]/3;
                rem+=ar[i]%3;
            }
            else if(rem!=0)
            {
                while((ar[i]>1)&&(rem>0))
                {
                    ar[i]-=2;
                    rem--;
                    gr++;

                }

                gr+=ar[i]/3;
                rem+=ar[i]%3;
            }
        }
        else
        {
            rem=rem+ar[i]%3;
        }

    }

    printf("%lld\n",gr);
return 0;
}


#include<stdio.h>

int main()
{
    long long int N,i, gr=0, rem=0;

    scanf("%lld", &N);
    long long int ar[N];
    for(i=0;i<N;i++)
    {
        scanf("%lld", &ar[i]);
    }
    for(i=0;i<N;i++)
    {
        if(i!=0)
        {
            if(ar[i]>=2)
            {
                if(rem==0)
                {
                    gr+=ar[i]/3;
                    rem+=ar[i]%3;
                }
               else if(rem!=0)
                {
                    while((ar[i]>0)&& (rem>0))
                    {
                        ar[i]-=2;
                        rem--;
                        gr++;

                     }
                    gr+=ar[i]/3;
                    rem+=ar[i]%3;

                }
            }
        }

        if(i==0)
        {
            gr+=ar[i]/3;
            rem+=ar[i]%3;
        }

    }

    printf("%lld\n",gr);
return 0;
}


#include<stdio.h>
#include<stdlib.h>
int read()
{
	int x=0;
	char ch = getchar();
	while( ch<'0' || ch>'9' ) ch = getchar();
	while( ch>='0' && ch<='9' ){
		x = (x<<3) + (x<<1) + ch - 48;
		ch = getchar();
	}
	return x;
}
int a[300005]={};
int main()
{
	int n;
	long long pair=0, ans=0; //见祖宗警告
	n = read();
	for( int i=0; i<n; i++ )
		a[i] = read();
	for( int i=n-1; i>=0; i-- ){ //只可能搭出等边和等腰三角形
		pair += a[i]>>1; // 2^i 有 a[i]/2 对
		if( a[i]%2 && pair ){ //如果pair大于0 就抽出一个pair和多出来的 2^i 边 凑成等腰或等边
			pair--; //一个pair等于两条大于等于 2^i 边 可以凑成等腰或等边
			ans++;
		}
	}
	ans += 2*pair/3; //剩下总共 2*pair 条边 任意两条目前最长边加一条最短边可以凑成一个三角形（凑完后把边个数删去）
	printf("%lld\n", ans);
	//system("pause");
	return 0;
}


#include<stdio.h>
#include<string.h>
int n,i;
long long a[600000];
long long sum,ans;
int main()
{
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%I64d",&a[i]);
		ans+=a[i]/3;
		a[i]%=3;
	}
	sum=0;
    for(i=0;i<n;i++)
    if(a[i]==1)sum++;
    else if(a[i]==2)
         if(sum>0){
         	ans++;
         	sum--;
		 }
		 else sum+=2;
	printf("%I64d",ans);
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            int n = ReadInt();
            long[] a = ReadLongArray();
            long[] e = new long[n];
            for (int i = 0; i < n; i++)
            {
                e[i] = a[i] % 3;
            }
            long[] pe = new long[n + 1];
            for (int i = 0; i < n; i++)
            {
                pe[i + 1] = pe[i] + e[i];
            }

            long ans = 0;
            long c2 = 0;
            long c4 = 0;
            long bon = 0;
            for (int i = n - 1; i >= 0; i--)
            {
                long ex = pe[i];
                if (a[i] != 1)
                {
                    long d = a[i] % 3;
                    if (d == 0)
                    {
                        ans += a[i] / 3;
                    }
                    if (d == 1)
                    {
                        if (c2 + 2 * c4 + 2 <= ex)
                        {
                            ans += (a[i] - 4) / 3;
                            c4++;
                        }
                        else
                        {
                            ans += a[i] / 3;
                        }
                    }
                    if (d == 2)
                    {
                        ans += a[i] / 3;
                        c2++;
                    }
                }
                bon = Math.Max(bon, Math.Min(ex, c2 + 2 * c4));
                /*if (2 * c4 - (ex - c2) > 0)
                {
                    long t = 2 * c4 - (ex - c2);
                    t /= 2;
                    bon = Math.Max(bon, ex + t);
                }*/
            }

            ans += bon;

            Writer.WriteLine(ans);
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                // Writer.WriteLine("Case {0}:", i + 1);
                // Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

#if DEBUG
            sw.Stop();
            // Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            // Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            int n = ReadInt();
            long[] a = ReadLongArray();

            long c = 0;
            long ans = 0;
            for (int i = 0; i < n; i++)
            {
                long d = Math.Min(c, a[i] / 2);
                c -= d;
                ans += d;
                a[i] -= 2 * d;
                ans += a[i] / 3;
                c += a[i] % 3;
            }

            Writer.WriteLine(ans);
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                // Writer.WriteLine("Case {0}:", i + 1);
                // Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

#if DEBUG
            sw.Stop();
            // Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            // Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            int n = ReadInt();
            long[] a = ReadLongArray();

            long[] e = new long[n];
            long[] x = new long[n];
            for (int i = 0; i < n; i++)
            {
                e[i] = a[i] % 3;
                x[i] = a[i] / 3;
            }
            long[] pe = new long[n + 1];
            long[] px = new long[n + 1];
            for (int i = 0; i < n; i++)
            {
                pe[i + 1] = pe[i] + e[i];
                px[i + 1] = px[i] + x[i];
            }

            long[] h = new long[n];
            long[] y = new long[n];
            for (int i = 0; i < n; i++)
            {
                y[i] = a[i] / 3;
                if (a[i] != 1)
                {
                    long d = a[i] % 3;
                    if (d == 1)
                    {
                        h[i] += 2;
                        y[i]--;
                    }
                    if (d == 2)
                    {
                        h[i] += 1;
                    }
                }
            }
            long[] ph = new long[n + 1];
            long[] py = new long[n + 1];
            for (int i = n - 1; i >= 0; i--)
            {
                ph[i] += ph[i + 1] + h[i];
                py[i] += py[i + 1] + y[i];
            }

            long ans = 0;
            for (int i = 0; i <= n; i++)
            {
                long d = px[i] + py[i];
                ans = Math.Max(ans, d + Math.Min(pe[i], ph[i]));

                long z = ph[i] - pe[i];
                long rem = (z + 2) / 3;
                rem = Math.Min(px[i], rem);
                d -= rem;
                pe[i] += rem * 3;
                ans = Math.Max(ans, d + Math.Min(pe[i], ph[i]));
            }

            Writer.WriteLine(ans);
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                // Writer.WriteLine("Case {0}:", i + 1);
                // Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

#if DEBUG
            sw.Stop();
            // Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            // Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            int n = ReadInt();
            long[] a = ReadLongArray();
            long[] e = new long[n];
            long ans1 = GetAns(n, e, a);

            e = new long[n];
            for (int i = 0; i < n; i++)
            {
                if (a[i] >= 3)
                {
                    a[i] -= 3;
                    e[i] += 3;
                }
            }
            long ans2 = GetAns(n, e, a);

            long ans = Math.Max(ans1, ans2);

            Writer.WriteLine(ans);
        }

        private static long GetAns(int n, long[] e, long[] a)
        {
            for (int i = 0; i < n; i++)
            {
                e[i] += a[i] % 3;
            }
            long[] pe = new long[n + 1];
            for (int i = 0; i < n; i++)
            {
                pe[i + 1] = pe[i] + e[i];
            }

            long ans = 0;
            long c2 = 0;
            long c4 = 0;
            long bon = 0;
            for (int i = n - 1; i >= 0; i--)
            {
                long ex = pe[i];
                if (a[i] != 1)
                {
                    long d = a[i] % 3;
                    if (d == 0)
                    {
                        ans += a[i] / 3;
                    }
                    if (d == 1)
                    {
                        if (c2 + 2 * c4 + 2 <= ex)
                        {
                            ans += (a[i] - 4) / 3;
                            c4++;
                        }
                        else
                        {
                            ans += a[i] / 3;
                        }
                    }
                    if (d == 2)
                    {
                        ans += a[i] / 3;
                        c2++;
                    }
                }
                bon = Math.Max(bon, Math.Min(ex, c2 + 2 * c4));
                /*if (2 * c4 - (ex - c2) > 0)
                {
                    long t = 2 * c4 - (ex - c2);
                    t /= 2;
                    bon = Math.Max(bon, ex + t);
                }*/
            }

            ans += bon;
            return ans;
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                // Writer.WriteLine("Case {0}:", i + 1);
                // Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

#if DEBUG
            sw.Stop();
            // Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            // Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            int n = ReadInt();
            long[] a = ReadLongArray();

            long[] e = new long[n];
            long[] x = new long[n];
            for (int i = 0; i < n; i++)
            {
                e[i] = a[i] % 3;
                x[i] = a[i] / 3;
            }
            long[] pe = new long[n + 1];
            long[] px = new long[n + 1];
            for (int i = 0; i < n; i++)
            {
                pe[i + 1] = pe[i] + e[i];
                px[i + 1] = px[i] + x[i];
            }

            long[] h = new long[n];
            long[] y = new long[n];
            for (int i = 0; i < n; i++)
            {
                y[i] = a[i] / 3;
                if (a[i] != 1)
                {
                    long d = a[i] % 3;
                    if (d == 1)
                    {
                        h[i] += 2;
                        y[i]--;
                    }
                    if (d == 2)
                    {
                        h[i] += 1;
                    }
                }
            }
            long[] ph = new long[n + 1];
            long[] py = new long[n + 1];
            for (int i = n - 1; i >= 0; i--)
            {
                ph[i] += ph[i + 1] + h[i];
                py[i] += py[i + 1] + y[i];
            }

            long ans = 0;
            for (int i = 0; i <= n; i++)
            {
                long d = px[i] + py[i];
                d += Math.Min(pe[i], ph[i]);
                ans = Math.Max(ans, d);
            }

            Writer.WriteLine(ans);
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                // Writer.WriteLine("Case {0}:", i + 1);
                // Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

#if DEBUG
            sw.Stop();
            // Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            // Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            int n = ReadInt();
            long[] a = ReadLongArray();

            long[] e = new long[n];
            long[] x = new long[n];
            for (int i = 0; i < n; i++)
            {
                e[i] = a[i] % 3;
                x[i] = a[i] / 3;
            }
            long[] pe = new long[n + 1];
            long[] px = new long[n + 1];
            for (int i = 0; i < n; i++)
            {
                pe[i + 1] = pe[i] + e[i];
                px[i + 1] = px[i] + x[i];
            }

            long[] h = new long[n];
            long[] y = new long[n];
            for (int i = 0; i < n; i++)
            {
                y[i] = a[i] / 3;
                if (a[i] != 1)
                {
                    long d = a[i] % 3;
                    if (d == 1)
                    {
                        h[i] += 2;
                        y[i]--;
                    }
                    if (d == 2)
                    {
                        h[i] += 1;
                    }
                }
            }
            long[] ph = new long[n + 1];
            long[] py = new long[n + 1];
            for (int i = n - 1; i >= 0; i--)
            {
                ph[i] += ph[i + 1] + h[i];
                py[i] += py[i + 1] + y[i];
            }

            long ans = 0;
            for (int i = 0; i <= n; i++)
            {
                long d = px[i] + py[i];
                ans = Math.Max(ans, d + Math.Min(pe[i], ph[i]));

                long z = ph[i] - pe[i];
                if (z > 0)
                {
                    long rem = (z + 2) / 3;
                    rem = Math.Min(px[i], rem);
                    d -= rem;
                    pe[i] += rem * 3;
                    ans = Math.Max(ans, d + Math.Min(pe[i], ph[i]));
                }
            }

            Writer.WriteLine(ans);
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                // Writer.WriteLine("Case {0}:", i + 1);
                // Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

#if DEBUG
            sw.Stop();
            // Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            // Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading;

namespace ReadWriteTemplate
{
    public static class Solver
    {
        private static void SolveCase()
        {
            int n = ReadInt();
            long[] a = ReadLongArray();
            long[] e = new long[n];
            long ans1 = GetAns(n, e, a);

            e = new long[n];
            for (int i = 0; i < n; i++)
            {
                if (a[i] >= 3)
                {
                    a[i] -= 3;
                    e[i] += 3;
                    break;
                }
            }
            long ans2 = GetAns(n, e, a);

            long ans = Math.Max(ans1, ans2);

            Writer.WriteLine(ans);
        }

        private static long GetAns(int n, long[] e, long[] a)
        {
            for (int i = 0; i < n; i++)
            {
                e[i] += a[i] % 3;
            }
            long[] pe = new long[n + 1];
            for (int i = 0; i < n; i++)
            {
                pe[i + 1] = pe[i] + e[i];
            }

            long ans = 0;
            long c2 = 0;
            long c4 = 0;
            long bon = 0;
            for (int i = n - 1; i >= 0; i--)
            {
                long ex = pe[i];
                if (a[i] != 1)
                {
                    long d = a[i] % 3;
                    if (d == 0)
                    {
                        ans += a[i] / 3;
                    }
                    if (d == 1)
                    {
                        if (c2 + 2 * c4 + 2 <= ex)
                        {
                            ans += (a[i] - 4) / 3;
                            c4++;
                        }
                        else
                        {
                            ans += a[i] / 3;
                        }
                    }
                    if (d == 2)
                    {
                        ans += a[i] / 3;
                        c2++;
                    }
                }
                bon = Math.Max(bon, Math.Min(ex, c2 + 2 * c4));
                /*if (2 * c4 - (ex - c2) > 0)
                {
                    long t = 2 * c4 - (ex - c2);
                    t /= 2;
                    bon = Math.Max(bon, ex + t);
                }*/
            }

            ans += bon;
            return ans;
        }

        public static void Solve()
        {
#if DEBUG
            var sw = Stopwatch.StartNew();
#endif

            SolveCase();

            /*int T = ReadInt();
            for (int i = 0; i < T; i++)
            {
                // Writer.WriteLine("Case {0}:", i + 1);
                // Writer.Write("Case #{0}: ", i + 1);
                SolveCase();
            }*/

#if DEBUG
            sw.Stop();
            // Console.WriteLine($"{sw.ElapsedMilliseconds} ms");
#endif
        }

        public static void Main()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

#if DEBUG
            // Reader = Console.In; Writer = Console.Out;
            Reader = File.OpenText("input.txt"); Writer = File.CreateText("output.txt");
#else
            Reader = Console.In; Writer = Console.Out;
#endif

            // Solve();
            Thread thread = new Thread(Solve, 64 * 1024 * 1024);
            thread.CurrentCulture = CultureInfo.InvariantCulture;
            thread.Start();
            thread.Join();

            Reader.Close();
            Writer.Close();
        }

        public static IOrderedEnumerable<TSource> OrderByWithShuffle<TSource, TKey>(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
        {
            return source.Shuffle().OrderBy(keySelector);
        }

        public static T[] Shuffle<T>(this IEnumerable<T> source)
        {
            T[] result = source.ToArray();
            Shuffle(result);
            return result;
        }

        private static void Shuffle<T>(IList<T> array)
        {
            Random rnd = new Random();
            for (int i = array.Count - 1; i >= 1; i--)
            {
                int k = rnd.Next(i + 1);
                T tmp = array[k];
                array[k] = array[i];
                array[i] = tmp;
            }
        }

        #region Read/Write

        private static TextReader Reader;

        private static TextWriter Writer;

        private static Queue<string> CurrentLineTokens = new Queue<string>();

        private static string[] ReadAndSplitLine()
        {
            return Reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
        }

        public static string ReadToken()
        {
            while (CurrentLineTokens.Count == 0)
                CurrentLineTokens = new Queue<string>(ReadAndSplitLine());
            return CurrentLineTokens.Dequeue();
        }

        public static string ReadLine()
        {
            return Reader.ReadLine();
        }

        public static int ReadInt()
        {
            return int.Parse(ReadToken());
        }

        public static long ReadLong()
        {
            return long.Parse(ReadToken());
        }

        public static double ReadDouble()
        {
            return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
        }

        public static int[] ReadIntArray()
        {
            return ReadAndSplitLine().Select(int.Parse).ToArray();
        }

        public static long[] ReadLongArray()
        {
            return ReadAndSplitLine().Select(long.Parse).ToArray();
        }

        public static double[] ReadDoubleArray()
        {
            return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
        }

        public static int[][] ReadIntMatrix(int numberOfRows)
        {
            int[][] matrix = new int[numberOfRows][];
            for (int i = 0; i < numberOfRows; i++)
                matrix[i] = ReadIntArray();
            return matrix;
        }

        public static string[] ReadLines(int quantity)
        {
            string[] lines = new string[quantity];
            for (int i = 0; i < quantity; i++)
                lines[i] = Reader.ReadLine().Trim();
            return lines;
        }

        public static void WriteArray<T>(IEnumerable<T> array)
        {
            Writer.WriteLine(string.Join(" ", array));
        }

        #endregion
    }
}


using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using static System.Console;
using static System.Math;
class Z { static void Main() => new K(); }
class K
{
	int F => int.Parse(Str);
	long FL => long.Parse(Str);
	int[] G => Strs.Select(int.Parse).ToArray();
	uint[] GU => Strs.Select(uint.Parse).ToArray();
	decimal[] GD => Strs.Select(decimal.Parse).ToArray();
	long[] GL => Strs.Select(long.Parse).ToArray();
	string Str => ReadLine();
	string[] Strs => Str.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
	static T[] ConstantArray<T>(int n, T val) { var a = new T[n]; for (var i = 0; i < n; i++) a[i] = val; return a; }
	static T[] MakeArray<T>(int n, Func<int, T> f) { var a = new T[n]; for (var i = 0; i < n; i++) a[i] = f(i); return a; }
	static ulong One(int k) => 1ul << k;
	static ulong All(int k) => One(k) - 1;
	static bool Has(ulong s, int k) => (s & One(k)) != 0;
	const int MOD = 1000000007;
	public K()
	{
		SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
		Solve();
		Out.Flush();
	}
	void Solve()
	{
		var N = F;
		var a = G;
		var s = 0L;
		var l = 0L;
		for (var i = 0; i < N; i++)
		{
			if (a[i] >= 2 * l)
			{
				a[i] = (int)(a[i] - 2 * l);
				s += l + a[i] / 3;
				l = a[i] % 3;
			}
			else
			{
				s += a[i] / 2;
				l = l - a[i] / 2 + a[i] % 2;
			}
		}
		WriteLine(s);
	}
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace contest
{
    class Program
    {
#if DEBUG
        static readonly TextReader input = File.OpenText(@"../../A/A.in");
        static readonly TextWriter output = File.CreateText(@"../../A/A.out");
#else
        static readonly TextReader input = Console.In;
        static readonly TextWriter output = Console.Out;
#endif

        private static void SolveA()
        {
            input.ReadLine();
            long[] s = input.ReadLine().Split(' ').Select(long.Parse).ToArray();

            long sum = s.Sum();
            long pending = 0;
            long complete = 0;
            for (int i = s.Length - 1; i >= 0; --i)
            {
                // x + pending <= sum - 2*x;
                // 3 * x <= -pending + sum;

                long x = Math.Min(s[i]/2, (sum - pending) / 3);
                x = Math.Max(0, x);

                long remain = s[i] - 2 * x;
                pending += x;

                long newComplete = Math.Min(remain, pending);
                complete += newComplete;
                pending -= newComplete;
                sum -= s[i];
            }

            output.WriteLine(complete);
        }

        static void Main(string[] args)
        {
            //SolveC();
            SolveA();
            output.Flush();
        }
    }
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		int dpmax = 3;
		long[,]D = new long[N+1,dpmax+1];
		for(var i=1;i<dpmax+1;i++){
    		D[N,i] = -999999999;
		}
		for(var i=N-1;i>=0;i--){
		    long[,]a = new long[dpmax+1,dpmax+1];
		    for(var j=0;j<dpmax+1;j++){
		        for(var k=0;k<dpmax+1;k++){
		            a[j,k] = -999999999;
		            if(k-j>=0){
    		            if(A[i] >= (k-j)*2){
	    	                a[j,k] = (A[i]-(k-j)*2)/3;
		                }
		            } else {
                        if(A[i] >= j-k){
                            a[j,k] = (A[i]-(j-k))/3+j-k;
		                }
		            }
		        }
		    }
			for(var k=0;k<dpmax+1;k++){
			    D[i,k] = -999999999;
			    for(var l=0;l<dpmax+1;l++){
			        D[i,k] = Math.Max(D[i,k],D[i+1,l]+a[l,k]);
			    }
                //D[i,k] = Math.Max(Math.Max(D[i+1,0]+a[0,k],D[i+1,1]+a[1,k]),D[i+1,2]+a[2,k]);
			}
		}
		//for(var i=Math.Max(0,N-10);i<N+1;i++){
		//    for(var j=0;j<dpmax+1;j++){
        //	    Console.Write(D[i,j]+" ");
        //    }
        //    Console.WriteLine();
		//}
		long ansA = D[0,0];
		for(var i=1;i<dpmax+1;i++){
		    ansA = Math.Max(ansA,D[0,i]);
		}
		Console.WriteLine(ansA);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		int dpmax = 20;
		long[,]D = new long[N+1,dpmax+1];
		for(var i=1;i<dpmax+1;i++){
    		D[N,i] = -999999999;
		}
		for(var i=N-1;i>=0;i--){
		    long[,]a = new long[dpmax+1,dpmax+1];
		    for(var j=0;j<dpmax+1;j++){
		        for(var k=0;k<Math.Min(dpmax+1,j+A[i]+1);k++){
		            //a[j,k] = -999999999;
		            if(k-j>=0){
    		            if(A[i] >= (k-j)*2){
	    	                a[j,k] = (A[i]-(k-j)*2)/3+1;
		                }
		            } else {
                        if(A[i] >= j-k){
                            a[j,k] = (A[i]-(j-k))/3+j-k+1;
		                }
		            }
		        }
		    }
			for(var k=0;k<dpmax+1;k++){
			    D[i,k] = -999999999;
			    for(var l=0;l<dpmax+1;l++){
			        if(a[l,k] > 0){
    			        D[i,k] = Math.Max(D[i,k],D[i+1,l]+a[l,k]-1);
			        }
			    }
                //D[i,k] = Math.Max(Math.Max(D[i+1,0]+a[0,k],D[i+1,1]+a[1,k]),D[i+1,2]+a[2,k]);
			}
		}
		//for(var i=Math.Max(0,N-10);i<N+1;i++){
		//    for(var j=0;j<dpmax+1;j++){
        //	    Console.Write(D[i,j]+" ");
        //    }
        //    Console.WriteLine();
		//}
		long ansA = D[0,0];
		for(var i=1;i<dpmax+1;i++){
		    ansA = Math.Max(ansA,D[0,i]);
		}
		Console.WriteLine(ansA);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		int dpmax = 16;
		long[,]D = new long[N+1,dpmax+1];
		for(var i=1;i<dpmax+1;i++){
    		D[N,i] = -999999999;
		}
		for(var i=N-1;i>=0;i--){
		    long[,]a = new long[dpmax+1,dpmax+1];
		    for(var j=0;j<dpmax+1;j++){
		        for(var k=0;k<dpmax+1;k++){
		            a[j,k] = -999999999;
		            if(k-j>=0){
    		            if(A[i] >= (k-j)*2){
	    	                a[j,k] = (A[i]-(k-j)*2)/3;
		                }
		            } else {
                        if(A[i] >= j-k){
                            a[j,k] = (A[i]-(j-k))/3+j-k;
		                }
		            }
		        }
		    }
			for(var k=0;k<dpmax+1;k++){
			    D[i,k] = D[i+1,0]+a[0,k];
			    for(var l=1;l<dpmax+1;l++){
			        D[i,k] = Math.Max(D[i,k],D[i+1,l]+a[l,k]);
			    }
                //D[i,k] = Math.Max(Math.Max(D[i+1,0]+a[0,k],D[i+1,1]+a[1,k]),D[i+1,2]+a[2,k]);
			}
		}
		//for(var i=Math.Max(0,N-10);i<N+1;i++){
		//    for(var j=0;j<dpmax+1;j++){
        //	    Console.Write(D[i,j]+" ");
        //    }
        //    Console.WriteLine();
		//}
		long ansA = D[0,0];
		for(var i=1;i<dpmax+1;i++){
		    ansA = Math.Max(ansA,D[0,i]);
		}
		Console.WriteLine(ansA);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		int dpmax = 20;
		long[,]D = new long[N+1,dpmax+1];
		for(var i=1;i<dpmax+1;i++){
    		D[N,i] = -999999999;
		}
		for(var i=N-1;i>=0;i--){
		    long[,]a = new long[dpmax+1,dpmax+1];
		    for(var j=0;j<dpmax+1;j++){
		        for(var k=0;k<dpmax+1;k++){
		            a[j,k] = -999999999;
		            if(k-j>=0){
    		            if(A[i] >= (k-j)*2){
	    	                a[j,k] = (A[i]-(k-j)*2)/3;
		                }
		            } else {
                        if(A[i] >= j-k){
                            a[j,k] = (A[i]-(j-k))/3+j-k;
		                }
		            }
		        }
		    }
			for(var k=0;k<dpmax+1;k++){
			    D[i,k] = -999999999;
			    for(var l=0;l<dpmax+1;l++){
			        D[i,k] = Math.Max(D[i,k],D[i+1,l]+a[l,k]);
			    }
                //D[i,k] = Math.Max(Math.Max(D[i+1,0]+a[0,k],D[i+1,1]+a[1,k]),D[i+1,2]+a[2,k]);
			}
		}
		//for(var i=Math.Max(0,N-10);i<N+1;i++){
		//    for(var j=0;j<dpmax+1;j++){
        //	    Console.Write(D[i,j]+" ");
        //    }
        //    Console.WriteLine();
		//}
		long ansA = D[0,0];
		for(var i=1;i<dpmax+1;i++){
		    ansA = Math.Max(ansA,D[0,i]);
		}
		Console.WriteLine(ansA);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		long ans = 0;
		int aj = 0;
		int ak = N-1;
		for(var i=N-1;i>=0;i--){
			if(A[i]%2==1 && A[i]>=3){
				A[i] -= 3;
				ans += 1;
			}
			while(A[i]>1){
                while(ak >= 0){
                    while(ak>=i){
                        ak--;
                    }
                    if(ak<0){
                        break;
                    }
                    if(A[ak]==1){
                        A[i] -= 2;
                        A[ak] = 0;
                        ans += 1;
                    } else {
                        ak--;
                    }
                    if(A[i]<=1){
                        break;
                    }
                }
                if(ak<0){
                    break;
                }
			}
			while(A[i]>1){
				if(A[aj]>=1 && aj<i){
					long ct = Math.Min(A[aj],A[i]/2);
					A[i] -= ct*2;
					A[aj] -= ct;
					ans += ct;
				} else {
					aj++;
					if(aj>i){
						break;
					}
				}
			}
			if(A[i]>=3){
			    ans += A[i]/3;
			    A[i] -= A[i]/3*3;
			}
		}
		Console.WriteLine(ans);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		int dpmax = 10;
		long[,]D = new long[N+1,dpmax+1];
		for(var i=1;i<dpmax+1;i++){
    		D[N,i] = -999999999;
		}
		for(var i=N-1;i>=0;i--){
		    long[,]a = new long[dpmax+1,dpmax+1];
		    for(var j=0;j<dpmax+1;j++){
		        for(var k=0;k<dpmax+1;k++){
		            a[j,k] = -999999999;
		            if(k-j>=0){
    		            if(A[i] >= (k-j)*2){
	    	                a[j,k] = (A[i]-(k-j)*2)/3;
		                }
		            } else {
                        if(A[i] >= j-k){
                            a[j,k] = (A[i]-(j-k))/3+j-k;
		                }
		            }
		        }
		    }
			for(var k=0;k<dpmax+1;k++){
			    D[i,k] = -999999999;
			    for(var l=0;l<dpmax+1;l++){
			        D[i,k] = Math.Max(D[i,k],D[i+1,l]+a[l,k]);
			    }
                //D[i,k] = Math.Max(Math.Max(D[i+1,0]+a[0,k],D[i+1,1]+a[1,k]),D[i+1,2]+a[2,k]);
			}
		}
		//for(var i=Math.Max(0,N-10);i<N+1;i++){
		//    for(var j=0;j<dpmax+1;j++){
        //	    Console.Write(D[i,j]+" ");
        //    }
        //    Console.WriteLine();
		//}
		long ansA = D[0,0];
		for(var i=1;i<dpmax+1;i++){
		    ansA = Math.Max(ansA,D[0,i]);
		}
		Console.WriteLine(ansA);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		int dpmax = 15;
		long[,]D = new long[N+1,dpmax+1];
		for(var i=1;i<dpmax+1;i++){
    		D[N,i] = -999999999;
		}
		for(var i=N-1;i>=0;i--){
		    long[,]a = new long[dpmax+1,dpmax+1];
		    for(var j=0;j<dpmax+1;j++){
		        for(var k=0;k<dpmax+1;k++){
		            a[j,k] = -999999999;
		            if(k-j>=0){
    		            if(A[i] >= (k-j)*2){
	    	                a[j,k] = (A[i]-(k-j)*2)/3;
		                }
		            } else {
                        if(A[i] >= j-k){
                            a[j,k] = (A[i]-(j-k))/3+j-k;
		                }
		            }
		        }
		    }
			for(var k=0;k<dpmax+1;k++){
			    D[i,k] = -999999999;
			    for(var l=0;l<dpmax+1;l++){
			        D[i,k] = Math.Max(D[i,k],D[i+1,l]+a[l,k]);
			    }
                //D[i,k] = Math.Max(Math.Max(D[i+1,0]+a[0,k],D[i+1,1]+a[1,k]),D[i+1,2]+a[2,k]);
			}
		}
		//for(var i=Math.Max(0,N-10);i<N+1;i++){
		//    for(var j=0;j<dpmax+1;j++){
        //	    Console.Write(D[i,j]+" ");
        //    }
        //    Console.WriteLine();
		//}
		long ansA = D[0,0];
		for(var i=1;i<dpmax+1;i++){
		    ansA = Math.Max(ansA,D[0,i]);
		}
		Console.WriteLine(ansA);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		int dpmax = 3;
		long[,]D = new long[N+1,dpmax+1];
		for(var i=1;i<dpmax+1;i++){
    		D[N,i] = -999999999;
		}
		for(var i=N-1;i>=0;i--){
		    long[,]a = new long[dpmax+1,dpmax+1];
		    for(var j=0;j<dpmax+1;j++){
		        for(var k=0;k<dpmax+1;k++){
		            a[j,k] = -999999999;
		            if(k-j>=0){
    		            if(A[i] >= (k-j)*2){
	    	                a[j,k] = (A[i]-(k-j)*2)/3;
		                }
		            } else {
                        if(A[i] >= j-k){
                            a[j,k] = (A[i]-(j-k))/3+j-k;
		                }
		            }
		        }
		    }
			for(var k=0;k<dpmax+1;k++){
			    for(var l=0;l<dpmax+1;l++){
			        D[i,k] = Math.Max(D[i,k],D[i+1,l]+a[l,k]);
			    }
                //D[i,k] = Math.Max(Math.Max(D[i+1,0]+a[0,k],D[i+1,1]+a[1,k]),D[i+1,2]+a[2,k]);
			}
		}
		//for(var i=Math.Max(0,N-10);i<N+1;i++){
		//    for(var j=0;j<dpmax+1;j++){
        //	    Console.Write(D[i,j]+" ");
        //    }
        //    Console.WriteLine();
		//}
		long ansA = D[0,0];
		for(var i=1;i<dpmax+1;i++){
		    ansA = Math.Max(ansA,D[0,i]);
		}
		Console.WriteLine(ansA);
	}
}


using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		int N = int.Parse(Console.ReadLine());
		string[] str = Console.ReadLine().Split();
		long[]A = new long[N];
		for(var i=0;i<N;i++){
			A[i] = long.Parse(str[i]);
		}
		long ans = 0;
		int aj = 0;
		int ak = N-1;
		for(var i=N-1;i>=0;i--){
			if(A[i]%2==1 && A[i]>=3){
				A[i] -= 3;
				ans += 1;
			}
			while(A[i]>1){
                while(ak >= 0){
                    while(ak>=i){
                        ak--;
                    }
                    if(ak<0){
                        break;
                    }
                    if(A[ak]==1){
                        A[i] -= 2;
                        A[ak] = 0;
                        ans += 1;
                    } else {
                        ak--;
                    }
                    if(A[i]<=1){
                        break;
                    }
                }
                if(ak<0){
                    break;
                }
			}
			while(A[i]>1){
				if(A[aj]>=1){
					long ct = Math.Min(A[aj],A[i]/2);
					A[i] -= ct*2;
					A[aj] -= ct;
					ans += ct;
				} else {
					aj++;
					if(aj>i){
						break;
					}
				}
			}
			if(A[i]>=3){
			    ans += A[i]/3;
			    A[i] -= A[i]/3*3;
			}
		}
		Console.WriteLine(ans);
	}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.IO;
using System.Text;
using System.Diagnostics;

using static util;
using P = pair<int, int>;

using Binary = System.Func<System.Linq.Expressions.ParameterExpression,
                           System.Linq.Expressions.ParameterExpression,
                           System.Linq.Expressions.BinaryExpression>;
using Unary = System.Func<System.Linq.Expressions.ParameterExpression,
                          System.Linq.Expressions.UnaryExpression>;

class Program {
    static StreamWriter sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
    static Scan sc = new Scan();
    const int M = 1000000007;
    const int M2 = 998244353;
    const long LM = 1L << 60;
    const double eps = 1e-11;
    static readonly int[] dd = { 0, 1, 0, -1, 0 };
    const string dstring = "RDLU";
    static void Main(string[] args)
    {
        int n = sc.Int;
        var a = sc.IntArr;
        long dcnt = 0;
        long ans = 0;
        for (int i = n - 1; i >= 0 ; i--)
        {
            dcnt += a[i] / 2;
            if (a[i] % 2 == 1 && dcnt > 0) {
                --dcnt;
                ++ans;
            }
        }
        Prt(ans + dcnt * 2 / 3);
        sw.Flush();
    }

    static void DBG(string a) => Console.WriteLine(a);
    static void DBG<T>(IEnumerable<T> a) => DBG(string.Join(" ", a));
    static void DBG(params object[] a) => DBG(string.Join(" ", a));
    static void Prt(string a) => sw.WriteLine(a);
    static void Prt<T>(IEnumerable<T> a) => Prt(string.Join(" ", a));
    static void Prt(params object[] a) => Prt(string.Join(" ", a));
}
class pair<T, U> : IComparable<pair<T, U>> {
    public T v1;
    public U v2;
    public pair() : this(default(T), default(U)) {}
    public pair(T v1, U v2) { this.v1 = v1; this.v2 = v2; }
    public int CompareTo(pair<T, U> a) {
        int c = Comparer<T>.Default.Compare(v1, a.v1);
        return c != 0 ? c : Comparer<U>.Default.Compare(v2, a.v2);
    }
    public override string ToString() => v1 + " " + v2;
    public void Deconstruct(out T a, out U b) { a = v1; b = v2; }
    public static bool operator>(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) > 0;
    public static bool operator<(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) < 0;
    public static bool operator>=(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) >= 0;
    public static bool operator<=(pair<T, U> a, pair<T, U> b) => a.CompareTo(b) <= 0;
}
static class util {
    public static pair<T, U> make_pair<T, U>(T v1, U v2) => new pair<T, U>(v1, v2);
    public static T sq<T>(T a) => Operator<T>.Multiply(a, a);
    public static T Max<T>(params T[] a) => a.Max();
    public static T Min<T>(params T[] a) => a.Min();
    public static bool inside(int i, int j, int h, int w) => i >= 0 && i < h && j >= 0 && j < w;
    public static void Assert(bool cond) { if (!cond) throw new Exception(); }
    public static Dictionary<T, int> compress<T>(this IEnumerable<T> a)
        => a.Distinct().OrderBy(v => v).Select((v, i) => new { v, i }).ToDictionary(p => p.v, p => p.i);
    public static Dictionary<T, int> compress<T>(params IEnumerable<T>[] a) => compress(a.Aggregate(Enumerable.Union));
    public static void swap<T>(ref T a, ref T b) where T : struct { var t = a; a = b; b = t; }
    public static void swap<T>(this IList<T> a, int i, int j) where T : struct { var t = a[i]; a[i] = a[j]; a[j] = t; }
    public static T[] copy<T>(this IList<T> a) {
        var ret = new T[a.Count];
        for (int i = 0; i < a.Count; i++) ret[i] = a[i];
        return ret;
    }
}
static class Operator<T> {
    static readonly ParameterExpression x = Expression.Parameter(typeof(T), "x");
    static readonly ParameterExpression y = Expression.Parameter(typeof(T), "y");
    public static readonly Func<T, T, T> Add = Lambda(Expression.Add);
    public static readonly Func<T, T, T> Subtract = Lambda(Expression.Subtract);
    public static readonly Func<T, T, T> Multiply = Lambda(Expression.Multiply);
    public static readonly Func<T, T, T> Divide = Lambda(Expression.Divide);
    public static readonly Func<T, T> Plus = Lambda(Expression.UnaryPlus);
    public static readonly Func<T, T> Negate = Lambda(Expression.Negate);
    public static Func<T, T, T> Lambda(Binary op) => Expression.Lambda<Func<T, T, T>>(op(x, y), x, y).Compile();
    public static Func<T, T> Lambda(Unary op) => Expression.Lambda<Func<T, T>>(op(x), x).Compile();
}

class Scan {
    StreamReader sr;
    public Scan() { sr = new StreamReader(Console.OpenStandardInput()); }
    public Scan(string path) { sr = new StreamReader(path); }
    public int Int => int.Parse(Str);
    public long Long => long.Parse(Str);
    public double Double => double.Parse(Str);
    public string Str => sr.ReadLine().Trim();
    public pair<T, U> Pair<T, U>() {
        T a; U b;
        Multi(out a, out b);
        return new pair<T, U>(a, b);
    }
    public P P => Pair<int, int>();
    public int[] IntArr => StrArr.Select(int.Parse).ToArray();
    public long[] LongArr => StrArr.Select(long.Parse).ToArray();
    public double[] DoubleArr => StrArr.Select(double.Parse).ToArray();
    public string[] StrArr => Str.Split(new[]{' '}, StringSplitOptions.RemoveEmptyEntries);
    bool eq<T, U>() => typeof(T).Equals(typeof(U));
    T ct<T, U>(U a) => (T)Convert.ChangeType(a, typeof(T));
    T cv<T>(string s) => eq<T, int>()    ? ct<T, int>(int.Parse(s))
                       : eq<T, long>()   ? ct<T, long>(long.Parse(s))
                       : eq<T, double>() ? ct<T, double>(double.Parse(s))
                       : eq<T, char>()   ? ct<T, char>(s[0])
                                         : ct<T, string>(s);
    public void Multi<T>(out T a) => a = cv<T>(Str);
    public void Multi<T, U>(out T a, out U b)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); }
    public void Multi<T, U, V>(out T a, out U b, out V c)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); }
    public void Multi<T, U, V, W>(out T a, out U b, out V c, out W d)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); }
    public void Multi<T, U, V, W, X>(out T a, out U b, out V c, out W d, out X e)
    { var ar = StrArr; a = cv<T>(ar[0]); b = cv<U>(ar[1]); c = cv<V>(ar[2]); d = cv<W>(ar[3]); e = cv<X>(ar[4]); }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using SB = System.Text.StringBuilder;
//using System.Text.RegularExpressions;
//using System.Globalization;
//using System.Diagnostics;
using static System.Console;
using System.Numerics;
using static System.Math;
using pair = Pair<int, int>;

class Program
{
    static void Main()
    {
        //SetOut(new StreamWriter(OpenStandardOutput()) { AutoFlush = false });
        new Program().solve();
        Out.Flush();
    }
    readonly Scanner cin = new Scanner();
    readonly int[] dd = { 0, 1, 0, -1, 0 }; //→↓←↑
    readonly int mod = 1000000007;
    readonly int dom = 998244353;
    bool chmax<T>(ref T a, T b) where T : IComparable<T> { if (a.CompareTo(b) < 0) { a = b; return true; } return false; }
    bool chmin<T>(ref T a, T b) where T : IComparable<T> { if (b.CompareTo(a) < 0) { a = b; return true; } return false; }

    void solve()
    {
        int N = cin.nextint;
        var A = cin.scanlong;

        long ans = 0;
        long remain = 0;
        for (int i = 0; i < N; i++)
        {
            var t = Min(remain, A[i] / 2);
            ans += t;
            remain -= t;
            A[i] -= t * 2;
            ans += A[i] / 3;
            remain += A[i] % 3;
        }
        WriteLine(ans);
        //var dp = new long[N + 1, 3];
        //dp[0, 0] = 1;

        //for (int i = 0; i < N; i++)
        //{
        //    for (int j = 0; j < 3; j++)
        //    {
        //        for (int k = 0; k < 3; k++)
        //        {

        //        }
        //    }
        //}
    }

}

static class Ex
{
    public static void join<T>(this IEnumerable<T> values, string sep = " ") => WriteLine(string.Join(sep, values));
    public static string concat<T>(this IEnumerable<T> values) => string.Concat(values);
    public static string reverse(this string s) { var t = s.ToCharArray(); Array.Reverse(t); return t.concat(); }

    public static int lower_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) < 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
    public static int upper_bound<T>(this IList<T> arr, T val) where T : IComparable<T>
    {
        int low = 0, high = arr.Count;
        int mid;
        while (low < high)
        {
            mid = ((high - low) >> 1) + low;
            if (arr[mid].CompareTo(val) <= 0) low = mid + 1;
            else high = mid;
        }
        return low;
    }
}

class Pair<T, U> : IComparable<Pair<T, U>> where T : IComparable<T> where U : IComparable<U>
{
    public T f; public U s;
    public Pair(T f, U s) { this.f = f; this.s = s; }
    public int CompareTo(Pair<T, U> a) => f.CompareTo(a.f) != 0 ? f.CompareTo(a.f) : s.CompareTo(a.s);
    public override string ToString() => $"{f} {s}";
}

class Scanner
{
    string[] s; int i;
    readonly char[] cs = new char[] { ' ' };
    public Scanner() { s = new string[0]; i = 0; }
    public string[] scan => ReadLine().Split();
    public int[] scanint => Array.ConvertAll(scan, int.Parse);
    public long[] scanlong => Array.ConvertAll(scan, long.Parse);
    public double[] scandouble => Array.ConvertAll(scan, double.Parse);
    public string next
    {
        get
        {
            if (i < s.Length) return s[i++];
            string st = ReadLine();
            while (st == "") st = ReadLine();
            s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
            i = 0;
            return next;
        }
    }
    public int nextint => int.Parse(next);
    public long nextlong => long.Parse(next);
    public double nextdouble => double.Parse(next);
}


#[allow(unused_imports)]
use std::cmp::*;
#[allow(unused_imports)]
use std::collections::*;
use std::io::{Write, BufWriter};
// https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8
macro_rules! input {
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, [ $t:tt ]) => {{
        let len = read_value!($next, usize);
        (0..len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    }};

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

fn solve() {
    let out = std::io::stdout();
    let mut out = BufWriter::new(out.lock());
    macro_rules! puts {
        ($($format:tt)*) => (write!(out,$($format)*).unwrap());
    }
    input! {
        n: usize,
        a: [i64; n],
    }
    let mut tot = 0;
    let mut rem = 0;
    for &a in &a {
        let t = min(a / 2, rem);
        let a = a - 2 * t;
        rem -= t;
        tot += t;

        tot += a / 3;
        let a = a % 3;
        rem += a;
    }
    puts!("{}\n", tot);
}

fn main() {
    // In order to avoid potential stack overflow, spawn a new thread.
    let stack_size = 104_857_600; // 100 MB
    let thd = std::thread::Builder::new().stack_size(stack_size);
    thd.spawn(|| solve()).unwrap().join().unwrap();
}


package main

import (
	"bufio"
	. "fmt"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func main() {
	in := bufio.NewReader(os.Stdin)
	var n, v, left int
	ans := int64(0)
	for Fscan(in, &n); n > 0; n-- {
		Fscan(in, &v)
		if left > 0 {
			if v > 2*left {
				ans += int64(left)
				v -= 2 * left
				left = 0
			} else {
				ans += int64(v / 2)
				left -= v / 2
				v %= 2
			}
		}
		ans += int64(v / 3)
		left += v % 3
	}
	Print(ans)
}


package main

import (
	"bufio"
	. "fmt"
	"io"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func CF1119E(_r io.Reader, out io.Writer) {
	in := bufio.NewReader(_r)
	var n, left int
	Fscan(in, &n)
	a := make([]int, n)
	for i := range a {
		Fscan(in, &a[i])
	}
	ans := int64(0)
	for _, v := range a {
		if left > 0 {
			if v > 2*left {
				ans += int64(left)
				v -= 2 * left
				left = 0
			} else {
				ans += int64(v / 2)
				left -= v / 2
				v %= 2
			}
		}
		ans += int64(v / 3)
		left += v % 3
	}
	Fprint(out, ans)
}

func main() { CF1119E(os.Stdin, os.Stdout) }


package main

import (
	"bufio"
	. "fmt"
	"os"
)

// github.com/EndlessCheng/codeforces-go
func main() {
	in := bufio.NewReader(os.Stdin)
	var n, left int
	Fscan(in, &n)
	a := make([]int, n)
	for i := range a {
		Fscan(in, &a[i])
	}
	ans := int64(0)
	for _, v := range a {
		if left > 0 {
			if v > 2*left {
				ans += int64(left)
				v -= 2 * left
				left = 0
			} else {
				ans += int64(v / 2)
				left -= v / 2
				v %= 2
			}
		}
		ans += int64(v / 3)
		left += v % 3
	}
	Print(ans)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	counter := int64(0)
	used := int64(0)
	for i := n - 1; i >= 0; i-- {
		if (left - used) / 3 > a[i] / 2 {
			left -= a[i]
			counter += a[i] / 2
			used += a[i] / 2 * 3 - a[i]
			if used < 0 {
				used = 0
			}
		} else {
			counter += (left - used) / 3
			break
		}
	}

	fmt.Println(counter)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int64) int64 {
	if a > b {
		return b
	}
	return a
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int64
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	used := int64(0)
	counter := int64(0)
	for i := n - 1; i >= 0; i-- {
		if (left - used) / 3 > a[i] / 2 {
			triangles := a[i] / 2
			left -= a[i]

			used += triangles * 3 - a[i]
			if used < 0 {
				left += used
				used = 0
			}
			counter += triangles
		} else {
			triangles := (left - used) / 3
			counter += triangles
			break
		}
	}

	fmt.Println(counter)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int64) int64 {
	if a > b {
		return b
	}
	return a
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int64
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	use := int64(0)
	counter := int64(0)
	for i := n - 1; i >= 0; i-- {
		triangles := min((left - use) / 3, a[i] / 2)
		left -= a[i]
		counter += triangles

		use += triangles * 3 - a[i]
		if left - use < 3 {
			break
		}
	}

	fmt.Println(counter)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int64) int64 {
	if a > b {
		return b
	}
	return a
}

func max(a, b int64) int64 {
	if a > b {
		return a
	}
	return b
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int64
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	used := int64(0)
	counter := int64(0)
	for i := n - 1; i >= 0; i-- {
		triangles := min((left - used) / 3, a[i] / 2)
		left -= a[i]
		counter += triangles

		used += max(triangles * 3 - a[i], 0)
		if left - used < 3 {
			break
		}
	}

	fmt.Println(counter)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int64) int64 {
	if a > b {
		return b
	}
	return a
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int64
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	use := int64(0)
	counter := int64(0)
	for i := n - 1; i >= 0; i-- {
		triangles := min((left - use) / 3, a[i] / 2)
		left -= a[i]
		counter += triangles

		use += triangles * 3 - a[i]

		if a[i] == 1 {
			if use == 0 {
				left--
			} else {
				use--
			}
		}
		if left < 3 {
			break
		}
	}

	fmt.Println(counter)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int64) int64 {
	if a > b {
		return b
	}
	return a
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int64
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	used := int64(0)
	counter := int64(0)
	for i := n - 1; i >= 0; i-- {
		triangles := min((left - used) / 3, a[i] / 2)
		counter += triangles
		left -= a[i]

		if triangles * 3 > a[i] {
			used += triangles * 3 - a[i]
		}
		if left - used < 3 {
			break
		}
	}

	fmt.Println(counter)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int64) int64 {
	if a > b {
		return b
	}
	return a
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int64
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	used := int64(0)
	counter := int64(0)
	/*for i := n - 1; i >= 0; i-- {
		triangles := min((left - used) / 3, a[i] / 2)
		counter += triangles
		left -= a[i]

		if triangles * 3 > a[i] {
			used += triangles * 3 - a[i]
		}
		//if left - used < 3 {
		//	break
		}
	}*/

	for i := n - 1; i >= 0; i-- {
		if left - used / 3 > a[i] / 2 {
			triangles := a[i] / 2
			left -= a[i]

			used += triangles * 3 - a[i]
			counter += triangles
		} else {
			triangles := (left - used) / 3
			counter += triangles
			break
		}
	}

	fmt.Println(counter)
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

func min(a, b int64) int64 {
	if a > b {
		return b
	}
	return a
}

func main() {
	in := bufio.NewReader(os.Stdin)

	var n int64
	fmt.Fscanln(in, &n)

	a := make([]int64, n)
	left := int64(0)
	for i := range a {
		fmt.Fscan(in, &a[i])
		left += a[i]
	}

	counter := int64(0)
	for i := n - 1; i >= 0; i-- {
		triangles := min(left / 3, a[i] / 2)
		left -= triangles * int64(3)
		counter += triangles

		if triangles == 0 && a[i] % 2 != 0 {
			left--
		}
		if left < 3 {
			break
		}
	}

	fmt.Println(counter)
}