#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <cstring>
#include <string>
#include <queue>
using namespace std;

typedef pair<int,int> P;
typedef pair<P, int> D;
typedef pair<P,P> PP;

class State {
public:
	vector<P> p;
	int nn;
	State(vector<P> p, int nn) : p(p), nn(nn) {}
};

class Node {
public:
	int pl, pr;
	vector<int> to;
	double R;
	int M;
	Node (int pl, int pr, vector<int> to, double R, int M)
		: pl(pl), pr(pr), to(to), R(R), M(M) {}
};

char map[62][10];
int pos[10];
vector<Node> tree;
vector<P> p;
queue<State> q;
int w, h;

int dx[] = { 1, 0, -1, 0 };
int dy[] = { 0, 1, 0, -1 };

bool xComp(const P& p1, const P&p2)
{
	if (p1.second == p2.second) return p1.first > p2.first;
	return p1.second < p2.second;
}

vector<P> connected(P p1, char c)
{
	queue<P> tq;
	tq.push(p1);
	vector<P> ret;
	bool v[62][10] = {0};
	while (!tq.empty())
	{
		P t=tq.front(); tq.pop();
		if (v[t.first][t.second]) continue;
		v[t.first][t.second] = true;
		ret.push_back(t);
		for (int i=0; i<4; i++)
		{
			int ny = t.first + dy[i];
			int nx = t.second + dx[i];
			if (nx<0||nx>=w||ny<0||ny>h) continue;
			if (v[ny][nx]) continue;
			if (map[ny][nx]!=c) continue;

			tq.push(P(ny, nx));
		}
	}

	return ret;
}

void dfs(int y, int x, char c)
{
	if (map[y][x]!=c) return;
	p.push_back(P(y, x));
	map[y][x] = '.';
	for (int i=0; i<4; i++)
	{
		int nx = x + dx[i];
		int ny = y + dy[i];
		if (nx<0||w<=nx||ny<1||h<ny) continue;
		if (map[ny][nx]!=c) continue;
		dfs(ny, nx, c);
	}
}

void make_tree()
{
	tree.clear();
	tree.push_back(Node(0, w, vector<int>(), -1.0, 0));
	p.clear();
	for (int i=0; i<w; i++)
		p.push_back(P(0, i));
	q.push(State(p, 0));

	while (!q.empty())
	{
		State t=q.front(); q.pop();
		queue<PP> tq;
		for (int i=0; i<t.p.size(); i++)
		{
			char c = map[t.p[i].first+1][t.p[i].second];
			if (c != '.')
			{
				int l=i, r=i;
				vector<P> ctd = connected(P(t.p[i].first+1, t.p[i].second), c);
				for (int j=0; j<4; j++)
				{
					P tp = P(t.p[i+j].first+1, t.p[i+j].second);
					if (i+j<t.p.size() && find(ctd.begin(), ctd.end(), tp) != ctd.end()) r = i+j;
				}

				tq.push(PP(t.p[i], P(t.p[l].second, t.p[r].second)));
				i = r;
			}
		}

		while (!tq.empty()) {
			PP tt=tq.front(); tq.pop();
			p.clear();
			dfs(tt.first.first+1, tt.first.second, map[tt.first.first+1][tt.first.second]);
			double r = 0;
			for (int i=0; i<p.size(); i++)
				r += (double) p[i].second;
			r /= 4.0;
			r += 0.5;
			int num = tree.size();
			tree.push_back(Node(tt.second.first, tt.second.second, vector<int>(), r, 4));
			tree[t.nn].to.push_back(num);

			sort(p.begin(), p.end(), xComp);
			memset(pos, 0, sizeof(pos));
			vector<P> tp;
			for (int i=0; i<p.size(); i++)
				if (!pos[p[i].second])
				{
					tp.push_back(p[i]);
					pos[p[i].second] = 1;
				}

			q.push(State(tp, num));
		}
	}
}

bool exec_recursive(int nn)
{
	if (tree[nn].to.size() > 0)
	{
		for (int i=0; i<tree[nn].to.size(); i++)
		{
			if (!exec_recursive(tree[nn].to[i])) return false;
			tree[nn].R = (tree[nn].M*tree[nn].R + tree[tree[nn].to[i]].M*tree[tree[nn].to[i]].R) / (tree[nn].M + tree[tree[nn].to[i]].M);
			tree[nn].M = tree[nn].M + tree[tree[nn].to[i]].M;
		}
		tree[nn].to.clear();
	}

	if (!(tree[nn].pl<tree[nn].R && tree[nn].R<tree[nn].pr+1.0)) return false;
	return true;
}

int main()
{
	while (cin >> w >> h, w||h)
	{
		for (int i=0; i<62; i++)
		for (int j=0; j<10; j++)
			map[i][j] = '.';

		for (int i=h; i>0; i--)
			cin >> map[i];

		make_tree();
		cout << ((exec_recursive(1)) ? string("STABLE") : string("UNSTABLE")) << endl;
	}

	return 0;
}

Measured memory_bytes: 0