import std.stdio,std.conv, std.algorithm, std.container,std.array,std.range,std.string,std.typecons,std.numeric,std.math,std.random,std.functional;
void main(){
	int w = 5,h;
	while(read(h),h){
		auto stones = readMatrix(w,h);
		const none = 0;
		int pts = 0;
		void Erace(){
			foreach(y;0..h){
				int s = stones[0,y],tot= 0,start = 0;
				foreach(x;0..w){
					if (stones[x,y] == s){ tot ++;continue;}
					if(tot >= 3) break;
					tot=1; s = stones[x,y];
					start = x;
				}
				if(tot < 3) continue;
				pts += s * tot;
				foreach(x;start .. start + tot) stones[x,y] = none;
			}
		}
		void Down(){
			foreach(x;0..w){
				foreach_reverse(y;0..h){
					if(stones[x,y])continue;
					foreach_reverse(yy;0..y){
						if(!stones[x,yy])continue;
						Swap(stones[x,y],stones[x,yy]);
						break;
					}	
				}
			}
		}
		for(int prepts = -1;prepts != pts;){
			prepts = pts;
			Erace();
			Down();
		}
		pts.writeln;
	}
}


const readMixin = q{ auto line = readln().split();foreach(i,ref arg; args){ if (i >= line.length) return;arg = line[i].to!(typeof(arg));}};
void read(T...)  (auto ref T args){mixin(readMixin);}
void readArray(T)(auto ref T args){mixin(readMixin);}
int  read(){int n;read(n);return n;}
const Dx = [1,0,-1,0], Dy = [0,1,0,-1];
const DPos = [Pos(1,0),Pos(0,1),Pos(-1,0),Pos(0,-1)];
void times(int n,void delegate() stmt){ foreach(i;0..n)stmt();}
void Swap(T)(ref T a,ref T b){T t = a;a = b;b = t;}
auto dot(R1,R2)(R1 a,R2 b) { 
	ElementType!(R1) res=0;
	for(;!a.empty&&!b.empty;a.popFront(),b.popFront())
		res+=a.front*b.front;
	return res;
}
struct infIota { 
	int i=0;
	enum empty=false;
	int front(){return i;}
	void popFront(){i++;}
}
struct Pos{ 
	int x,y,z;
	bool inRange(int w,int h,int Z=1){
		return x>=0 && y >= 0 && z >=0 && x < w && y < h && z < Z;
	}
	Pos opBinary(string op)(Pos rhs) {
		return Pos ( mixin( "x"~op~"rhs.x" ),
					 mixin( "y"~op~"rhs.y" ),
					 mixin( "z"~op~"rhs.z" ));
	}
	void opOpAssign(string op)(Pos lhs) {
		mixin("x"~op~"=lhs.x;");
		mixin("y"~op~"=lhs.y;");
		mixin("z"~op~"=lhs.z;");
	}
}
struct Matrix(T){
	private T[][] data;
	this(int w,int h){ data = new T[][](w,h);}
	this(ref T[][] data_){ data = data_;}
	T opIndexAssign(T v, size_t x, size_t y){return data[x][y] = v;}
	T opIndexAssign(T v, Pos p){return opIndexAssign(v,p.x,p.y);}
	ref T opIndex(size_t x, size_t y){return data[x][y];}
	ref T opIndex(Pos p){return opIndex(p.x,p.y);}
	ref T opCall(Pos p){return data[p.x][p.y];}
	auto W()const{return data.length;}	
	auto H()const{return data[0].length;}	
	auto X(int x){T[]res;foreach(y;0..H())res ~= data[x][y];return res; }
	auto Y(int y){T[]res;foreach(x;0..W())res ~= data[x][y];return res; }
	void setX(T[] vec, int x){foreach(int y,v;vec)data[x][y] = v; }
	void setY(T[] vec, int y){foreach(int x,v;vec)data[x][y] = v; }
	void toString(scope void delegate(const(char)[]) sink) const{
		foreach(y;0..H()) {
			foreach(x;0..W())sink(data[x][y].to!string);
			if(y != H()-1)sink("\n");
		}
    }
}
auto readAciiMap(int w,int h){ 
	auto M=new char[][](w,h);
	foreach(y;0..h) foreach(int x,c;readln().chomp) M[x][y] = c;		
	return Matrix!(char)(M);
}
auto readMatrix(int w,int h){
	auto M=new int[][](w,h);
	foreach(y;0..h) foreach(int x,c;readln().split()) M[x][y] = c.to!int;		
	return Matrix!(int)(M);
}