#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

struct Info{
	Info(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

int W,H;
char base_map[60][11];
int calc_map[60][11],table[151][60];
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,-1,1,0};
bool visited[151];
vector<int> V[151];
vector<Info> BLOCK[151];

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}

vector<int> getUpperPanelList(int panel_id){

	if(visited[panel_id])return V[panel_id];

	vector<int> ret,catcher;

	int tmp_row,tmp_col;
	for(int i = 0; i < 4; i++){
		tmp_row = BLOCK[panel_id][i].row;
		tmp_col = BLOCK[panel_id][i].col;

		if(tmp_row < H-1 && calc_map[tmp_row+1][tmp_col] != 0 && calc_map[tmp_row+1][tmp_col] != panel_id){
			ret.push_back(calc_map[tmp_row+1][tmp_col]);
			catcher = getUpperPanelList(calc_map[tmp_row+1][tmp_col]);
			for(int k = 0; k < catcher.size(); k++){
				ret.push_back(catcher[k]);
			}
		}
	}
	sort(ret.begin(),ret.end());
	ret.erase(unique(ret.begin(),ret.end()),ret.end());

	for(int i = 0; i < ret.size();i++){
		V[panel_id].push_back(ret[i]);
	}
	visited[panel_id] = true;
	return ret;
}


void func(){

	for(int i = 0; i <= 150; i++){
		visited[i] = false;
		V[i].clear();
		BLOCK[i].clear();
		for(int k = 0; k < 60; k++)table[i][k] = 0;
	}

	for(int row = H-1; row >= 0; row--){
		scanf("%s",base_map[row]);
		for(int col = 0; col < W; col++){
			calc_map[row][col] = -1;
		}
	}

	int label = 1;

	queue<Info> Q;
	int adj_row,adj_col;

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(base_map[row][col] == '.'){
				calc_map[row][col] = 0;
			}else{

				if(calc_map[row][col] == -1){
					calc_map[row][col] = label;

					table[label][col]++;
					BLOCK[label].push_back(Info(row,col));

					Q.push(Info(row,col));

					while(!Q.empty()){
						for(int i = 0; i < 4; i++){
							adj_row = Q.front().row+diff_row[i];
							adj_col = Q.front().col+diff_col[i];

							if(rangeCheck(adj_row,adj_col) == false || calc_map[adj_row][adj_col] != -1)continue;

							if(base_map[adj_row][adj_col] == base_map[row][col]){
								table[label][adj_col]++;
								calc_map[adj_row][adj_col] = label;
								BLOCK[label].push_back(Info(adj_row,adj_col));
								Q.push(Info(adj_row,adj_col));
							}

						}
						Q.pop();
					}
					label++;
				}
			}
		}
	}

	vector<int> ret;
	double XL,XR,bunbo,bunshi,jyushin;
	int tmp_row,tmp_col;

	int calc_table[W];

	for(int row = H-1; row >= 0; row--){
		for(int col = 0; col < W; col++){
			if(calc_map[row][col] == 0 || visited[calc_map[row][col]] == true)continue;

			XL = 1000.0,XR = -1000.0;

			for(int i = 0; i < 4; i++){
				tmp_row = BLOCK[calc_map[row][col]][i].row;
				tmp_col = BLOCK[calc_map[row][col]][i].col;

				if((tmp_row == 0) || (calc_map[tmp_row-1][tmp_col] != 0 && calc_map[tmp_row][tmp_col] != calc_map[tmp_row-1][tmp_col])){
					XL = min(XL,(double)tmp_col);
					XR = max(XR,(double)(tmp_col+1));
				}
			}

			ret = getUpperPanelList(calc_map[row][col]);

			for(int k = 0; k < W; k++){
				calc_table[k] = table[calc_map[row][col]][k];
			}

			for(int i = 0; i < ret.size(); i++){
				for(int k = 0; k < W; k++){
					calc_table[k] += table[ret[i]][k];
				}
			}

			bunbo = 0,bunshi = 0;
			for(int k = 0; k < W; k++){
				bunbo += calc_table[k];
				bunshi += (k+0.5)*(double)calc_table[k];
			}
			jyushin = bunshi/bunbo;

			if(jyushin <= XL || jyushin >= XR){
				printf("UNSTABLE\n");
				return;
			}
		}
	}

	printf("STABLE\n");
}


int main(){

	while(true){
		scanf("%d %d",&W,&H);
		if(W == 0 && H == 0)break;

		func();
	}

	return 0;
}

Measured memory_bytes: 3152