#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <cstring>
#include <queue>

using namespace std;

// int N;
// int MS[101];
// vector<map<char,char> > howToGet;
// map<map<char,char>,char> dp[43];
// void dfs(const int kind,int wgt,map<char,char> v){
//   if(kind==0){
//     map<char,char> nv=v;
//     dfs(kind+1,wgt,nv);
//   }
//   else if(wgt==0)howToGet.push_back(v);
//   else if(kind==10)return;
//   else{
//     for(int i=0;i*kind<=10;i++){
//       if(wgt-i*kind>=0){
// 	map<char,char> nv=v;
// 	if(i>=1)nv[kind]=i;
// 	dfs(kind+1,wgt-i*kind,nv);
//       }
//     }
//   }
// }

// void dfs2(const int pos,const map<char,char> v,int cnt,int &maxVal,int preLast){
//   if(pos==(int)howToGet.size())return;
//   if(preLast/10+cnt<=maxVal)return;
//   // 1セット分取れるか
//   map<char,char> nv=v;
//   bool ok=true;
//   int sz=0;
//   for(map<char,char>::iterator it=howToGet[pos].begin();it!=howToGet[pos].end();it++){
//     if(nv.count(it->first)==0
//        ||nv[it->first]-(it->second)<0){
//       ok=false;
//       break;
//     }
//     else{
//       nv[it->first]-=it->second;
//       sz+=it->second;
//     }
//   }
//   // 1セット取れるならとる
//   if(ok){
//     maxVal=max(maxVal,cnt+1);
//     dfs2(pos,nv,cnt+1,maxVal,preLast-sz);
//   }
//   // 取らずに次のセットへ
//   dfs2(pos+1,v,cnt,maxVal,preLast);
// }

// void greedy(int &maxVal,map<char,char> v){
//   for(int pos=0;pos<(int)howToGet.size();pos++){
//     while(1){
//       bool ok=true;
//       for(map<char,char>::iterator it=howToGet[pos].begin();it!=howToGet[pos].end();it++){
// 	if(v.count(it->first)==0||v[it->first]-(it->second)<0){
// 	  ok=false;
// 	  break;
// 	}
//       }
//       if(ok){
// 	for(map<char,char>::iterator it=howToGet[pos].begin();it!=howToGet[pos].end();it++)
// 	  v[it->first]-=it->second;
// 	maxVal++;
//       }
//       else
// 	break;
//     }
//   }
// }

// int main(){
//   dfs(0,10,map<char,char>());
//   while(cin>>N&&N){
//     map<char,char> cnts;
//     int preLast=0;
//     for(int i=0;i<N;i++)cin>>MS[i];
//     for(int i=0;i<N;i++){
//       cnts[MS[i]]++;
//       preLast+=MS[i];
//     }
//     for(int i=0;i<43;i++)dp[i].clear();
//     int maxVal=0;
//     greedy(maxVal,cnts);
//     // cout<<maxVal<<endl;
//     // dfs2(0,cnts,0,maxVal,preLast);
//     cout<<maxVal<<endl;
//   }
//   return 0;
// }

int N;
int MS[101];
vector<vector<char> > howToGet;
map<vector<char>,char> dp;
void dfs(int kind,int wgt,const vector<char> &v){
  if(kind==0){
    vector<char> nv=v;
    nv.push_back(0);
    dfs(kind+1,wgt,nv);
  }
  else if(wgt==0)howToGet.push_back(v);
  else if(kind==10)return;
  else{
    for(int i=0;i*kind<=10;i++){
      if(wgt-i*kind>=0){
	vector<char> nv=v;
	nv.push_back(i);
	dfs(kind+1,wgt-i*kind,nv);
      }
    }
  }
}

int dfs2(const vector<char> &v){
  if(dp.count(v)!=0)return dp[v];
  int res=0;
  for(int pos=0;pos<(int)howToGet.size();pos++){
    // 1セット分取れるか
    vector<char> nv=v;
    bool ok=true;
    for(int j=1;j<(int)howToGet[pos].size();j++){
      nv[j]-=howToGet[pos][j];
      if(nv[j]<0){
	ok=false;
	break;
      }
    }
    // iセット取れるならとる
    if(ok)res=max(res,dfs2(nv)+1);
  }
  return dp[v]=res;
}

int main(){
  dfs(0,10,vector<char>());
  while(cin>>N&&N){
    vector<char> cnts;
    for(int i=0;i<N;i++)cin>>MS[i];
    for(int i=0;i<=10;i++)cnts.push_back(0);
    for(int i=0;i<N;i++)cnts[MS[i]]++;
    int sum=0;
    // for(int i=1;i<=9;i++)
    //   cout<<(int)cnts[i]<<" ";
    // cout<<endl;
    for(int i=1;i<=4;i++){
      int a=min(cnts[i],cnts[10-i]);
      cnts[i]-=a;cnts[10-i]-=a;
      sum+=a;
    }
    int a=cnts[5]/2;
    cnts[5]-=2*a;
    sum+=a;
    //cout<<sum<<endl;
    int res=dfs2(cnts)+sum;
    cout<<res<<endl;
  }
  return 0;
}

Measured memory_bytes: 9420