#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>

using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vector<int> >;
using pii = pair<int, int>;
using ppi = pair<pii, int>;

int f_dir[2][4] = {{-1, 0, 1, 0}, {0, 1, 0, -1}}; //↑→↓←
bool is_in_field(int y, int x, int h, int w){
  return (y >= 0 && y < h && x >= 0 && x < w);
}

#define INF 100

struct block{
  int l, r;
  double M;
  vector<int> num;
  block(): l(INF), r(-INF){
    num = vi(10, 0);
  }
  void calc_m(){
    int acc = 0;
    double al = 0;
    for(int i = 0; i < 10; i++){
      al += (double)num[i] * (0.5 + i);
      acc += num[i];
    }
    M = al / acc;
  }
};

void renum(vvi &field, int w, int h){
  vvi tmp = field;
  vvi used(h, vi(w, 0));
  int num = 0;
  for(int i = 0; i < h; i++){
    for(int j = 0; j < w; j++){
      if(used[i][j] || field[i][j] == -1) continue;
      queue<pii> q;
      q.push({i, j});
      tmp[i][j] = num;
      while(!q.empty()){
        pii now = q.front(); q.pop();
        int n_x = now.second;
        int n_y = now.first;
        for(int k = 0; k < 4; k++){
          int nex_y = n_y + f_dir[0][k];
          int nex_x = n_x + f_dir[1][k];
          if(is_in_field(nex_y, nex_x, h, w)
          && !used[nex_y][nex_x]
          && field[n_y][n_x] == field[nex_y][nex_x]){
            tmp[nex_y][nex_x] = num;
            q.push({nex_y, nex_x});
            used[nex_y][nex_x] = 1;
          }
        }
      }
      num++;
    }
  }
  field = tmp;
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  int ti = clock();
  // start-----------------------------------------------
  int w,h;
  while(cin >> w >> h, w&&h){
    vector<vector<int>> field(h, vector<int>(w));
    vector<vector<bool>> rel(600, vector<bool>(600, false));
    bool ans = true;
    for(int i = h-1; i >= 0; i--){
      for(int j = 0; j < w; j++){
        char a;
        cin >> a;
        if(a == '.') field[i][j] = -1;
        else field[i][j] = (a - '1');
      }
    }

    renum(field, w, h);

    stack<int> st;
    vector<bool> used(600, false);
    vector<block> blocks(600);

    for(int i = 0; i < h; i++){
      for(int j = 0; j < w; j++){
        if(field[i][j] == -1) continue;
        if(!used[field[i][j]]){
          if(i == 0){
            st.push(field[i][j]);
            used[field[i][j]] = true;
          }
          else if(field[i-1][j] != -1 && field[i-1][j] != field[i][j]){
            st.push(field[i][j]);
            rel[field[i-1][j]][field[i][j]] = true;
            used[field[i][j]] = true;
          }
        }
        blocks[field[i][j]].num[j]++;
        if(i == 0 || (field[i-1][j] != -1 && field[i-1][j] != field[i][j])){
          blocks[field[i][j]].l = min(blocks[field[i][j]].l, j);
          blocks[field[i][j]].r = max(blocks[field[i][j]].r, j+1);
        }
      }
    }

    while(!st.empty()){
      int now = st.top(); st.pop();
      bool stable = true;
      for(int i = 0; i < 600; i++){
        if(!rel[now][i]) continue;
        for(int j = 0; j < w; j++){
          blocks[now].num[j] += blocks[i].num[j];
        }
      }
      blocks[now].calc_m();
      if(blocks[now].l >= blocks[now].M || blocks[now].r <= blocks[now].M) stable = false;
      if(!stable) ans = false;
    }
    cout << (ans ? "STABLE" : "UNSTABLE") << endl;
  }

  // end-----------------------------------------------
  // cerr << 1.0 * (clock() - ti) / CLOCKS_PER_SEC << endl;
}



Measured memory_bytes: 3248