#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <tuple>
#define rep(i, n) for(i = 0; i < n; i++)
#define rrep(i, n) for(i = n - 1; i >= 0; i--)
using namespace std;
typedef pair<int, int> P;

void chmin(int &a, int b) { a = min(a, b); }
void chmax(int &a, int b) { a = max(a, b); }

int dy[4] = {-1, 0, 1, 0};
int dx[4] = {0, 1, 0, -1};
int w, h;
string p[60];
int label[60][10], labelCnt;
vector<int> label_size;
vector<int> label_sumX;
vector<int> label_xl;
vector<int> label_xr;
vector<int> et[600];

void init() {
	labelCnt = 0;
	label_size.clear();
	label_sumX.clear();
	label_xl.clear();
	label_xr.clear();
	
	int i;
	rep(i, 600) {
		et[i].clear();
	}
}

void labeling() {
	int i, j;
	int id = 0;
	
	rep(i, h) rep(j, w) label[i][j] = -1;
	rrep(i, h) {
		rep(j, w) {
			if (p[i][j] == '.') continue;
			if (label[i][j] != -1) continue;
			
			queue<P> que;
			que.push(P(i, j));
			label[i][j] = id;
			
			while (!que.empty()) {
				P now = que.front(); que.pop();
				int y = now.first;
				int x = now.second;
				int dir;
				
				rep(dir, 4) {
					int ny = y + dy[dir];
					int nx = x + dx[dir];
					if (ny < 0 || ny >= h || nx < 0 || nx >= w) continue;
					if (p[ny][nx] != p[y][x]) continue;
					if (label[ny][nx] != -1) continue;
					
					que.push(P(ny, nx));
					label[ny][nx] = id;
				}
			}
			id++;
		}
	}
	labelCnt = id;
}

void makeData() {
	int i, j;
	
	label_size.resize(labelCnt);
	label_sumX.resize(labelCnt);
	label_xl.resize(labelCnt);
	label_xr.resize(labelCnt);
	
	rep(i, labelCnt) label_size[i] = 0;
	rep(i, h) {
		rep(j, w) {
			if (label[i][j] != -1) {
				label_size[label[i][j]]++;
				label_sumX[label[i][j]] += j;
			}
		}
	}
	
	rep(i, labelCnt) {
		label_xl[i] = w;
		label_xr[i] = 0;
	}
	
	rep(i, h - 1) {
		rep(j, w) {
			if (p[i][j] == '.') continue;
			if (p[i + 1][j] == '.') continue;
			if (p[i][j] == p[i + 1][j]) continue;
			int id = label[i][j];
			chmin(label_xl[id], j);
			chmax(label_xr[id], j + 1);
		}
	}
	
	rep(j, w) {
		if (p[h - 1][j] == '.') continue;
		int id = label[h - 1][j];
		chmin(label_xl[id], j);
		chmax(label_xr[id], j + 1);
	}
}

void makeTree() {
	int y, x, dir;
	
	rep(y, h) {
		rep(x, w) {
			if (label[y][x] == -1) continue;
			
			dir = 2;
			int ny = y + dy[dir];
			int nx = x + dx[dir];
			if (ny < 0 || ny >= h || nx < 0 || nx >= w) continue;
			if (label[ny][nx] == -1) continue;
			if (label[y][x] == label[ny][nx]) continue;
			
			int u = label[y][x];
			int v = label[ny][nx];
			et[u].push_back(v);
			et[v].push_back(u);
		}
	}
	
	int i;
	int lcnt = label_size.size();
	
	rep(i, lcnt) {
		sort(et[i].begin(), et[i].end());
		et[i].erase(unique(et[i].begin(), et[i].end()), et[i].end());
	}
}

bool check(int l, int r, int sz, int sumX) {
	double base = (double)sumX / sz + 0.5;
	double eps = 1e-10;
	
	//ギリギリダメ　→　ある
	//ギリギリOK → ない
	//少し厳しめに評価する
	return l + eps < base && base < r - eps;
}

typedef tuple<bool, int, int> T;	//(isOk, size, xsum)
T dfs(int p, int v) {
	int i;
	int _size = label_size[v];
	int _sumX = label_sumX[v];
	
	rep(i, et[v].size()) {
		int nv = et[v][i];
		if (nv == p) continue;
		T res = dfs(v, nv);
		if (!get<0>(res)) { return T(false, _size, _sumX); }
		_size += get<1>(res);
		_sumX += get<2>(res);
	}
	
	bool isOk = check(label_xl[v], label_xr[v], _size, _sumX);
	return T(isOk, _size, _sumX);
}

bool solve() {
	int i, j;
	
	labeling();
	makeData();
	makeTree();
	
	return get<0>(dfs(-1, 0));
}

int main() {
	while (cin >> w >> h) {
		if (!w) break;
		int i;
		rep(i, h) cin >> p[i];
		init();
		bool res = solve();
		if (res) cout << "STABLE" << endl;
		else cout << "UNSTABLE" << endl;
	}
	return 0;
}


Measured memory_bytes: 3104