#include<bits/stdc++.h>
#define eps 1e-8
using namespace std;
typedef complex<double> point;
class piece{
public:
  piece(vector<int> x, vector<int> y, int xr_, int xl_, int id_):
    xr(xr_), xl(xl_), id(id_){
    double gx = 0, gy = 0;
    for (int i = 0; i < x.size(); i++) {
      block.push_back(point(x[i], y[i]));
      gx += x[i] + 0.5;
      gy += y[i] + 0.5;
    }
    gravity = point(gx/x.size(), gy/y.size());
  };
  ~piece(){}
  inline void SetSupport(piece p){support.insert(p);}
  void SetRange(vector<string>& grid);
  inline int GetBlockSize(){return block.size();}
  inline point GetBlock(int id_){return block[id_];}
  inline point GetGrabity(){return gravity;}
  inline set<piece> GetSupport(){return support;}
  inline int GetSupportSize(){return support.size();}
  inline int GetId(){return id;}
  bool IsBalance(){
    double x = gravity.real()*block.size();
    int block_sum = block.size();
    for (piece i: support) {
      x += i.GetGrabity().real()*i.GetBlockSize();
      block_sum += i.GetBlockSize();
    }
    x /= block_sum;
    return (xl + eps < x && x < xr - eps + 1);
  }

  bool operator<(const piece p)const{
    return id < p.id;
  }
  void PrintPiece(){
    std::cout << "id:" << id << std::endl;
    std::cout << "xr:" << xr << " xl:" << xl << std::endl;
    std::cout << "gravity:" << gravity << std::endl;
    for (int i = 0; i < block.size(); i++) {
      std::cout << "block[" << i << "]:" << block[i] << std::endl;
    }
    for (piece i:support) {
      std::cout << "support:" << i.GetId() << std::endl;
    }
    std::cout << std::endl;
  }
  set<piece> support;
private:
  int xr, xl, id;
  point gravity;
  vector<point> block;
};
void piece::SetRange(vector<string>& grid){
  int h = grid.size();
  for (int i = 0; i < block.size(); i++) {
    int px = block[i].real(), py = block[i].imag();
    if(block[i].imag() == h - 1 ||
       (grid[py + 1][px] != '.' &&
        grid[py + 1][px] != grid[py][px])) {
      xr = max(xr, px);
      xl = min(xl, px);
    }
  }
}
void SetIndirectSupport(vector<piece>& vp, piece& p){
  if(p.GetSupportSize() == 0)return;
  set<piece> p_support = vp[p.GetId()].support;
  for (piece i: p_support) {
    //std::cout << p.GetId() << std::endl;
    //p.PrintPiece();
    SetIndirectSupport(vp, vp[i.GetId()]);
    //set<piece> i_support = 
    for (piece j: vp[i.GetId()].support) {
      p.SetSupport(j);
    }
  }
}


bool range(int x, int y, int w, int h){
  if(0 <= x && x < w &&
     0 <= y && y < h)return true;
  return false;
}

int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1};
void dfs(vector<string>& grid, vector<int>& x,
         vector<int>& y, int px, int py, char c){
  int w = grid[0].size(), h = grid.size();
  x.push_back(px);
  y.push_back(py);
  grid[py][px] = '.';
  for (int i = 0; i < 4; i++) {
    if(!range(px + dx[i], py + dy[i], w, h))continue;
    if(grid[py + dy[i]][px + dx[i]] == c){
      dfs(grid, x, y, px + dx[i], py + dy[i], c);
    }
  }
}

void printGrid(vector<string>& grid){
  for (int i = 0; i < grid.size(); i++) {
    std::cout << grid[i] << std::endl;
  }
  std::cout << std::endl;
}

bool IsSupport(vector<string>& grid, point b){
  if(b.imag() > 0 &&
     grid[b.imag() - 1][b.real()] != '.' &&
     grid[b.imag() - 1][b.real()] != grid[b.imag()][b.real()])
    return true;
  return false;
}
               

int main(int argc, char *argv[]){
  int w, h;
  while(std::cin >> w >> h, w){
    vector<string> grid(h);
    for (int i = 0; i < h; i++) {
      std::cin >> grid[i];
    }
    vector<piece> p;
    int cnt = 0;
    for (int i = h - 1; i >= 0; i--) {
      for (int j = 0; j < w; j++) {
        if(grid[i][j] != '.'){
          vector<int> x, y;
          int xr, xl;
          dfs(grid, x, y, j, i, grid[i][j]);
          p.push_back(piece(x, y, 0, 1e9, cnt));
          cnt++;
        }
      }
      
    }
    for (int i = 0; i < p.size(); i++) {
      for (int j = 0; j < p[i].GetBlockSize(); j++) {
        point b = p[i].GetBlock(j);
        grid[(int)b.imag()][(int)b.real()] = '0' + p[i].GetId();
      }
    }
    for (int i = 0; i < p.size(); i++) {
      p[i].SetRange(grid);
    }
    for (int i = 0; i < p.size(); i++) {
      for (int j = 0; j < p[i].GetBlockSize(); j++) {
        point b = p[i].GetBlock(j);
        if(IsSupport(grid, b)){
          int id = grid[b.imag() - 1][b.real()] - '0';
          p[i].SetSupport(p[id]);
        }
      }
    }
    SetIndirectSupport(p, p[0]);
    //std::cout << w << " " << h << std::endl;
    for (int i = 0; i < p.size(); i++) {
      //p[i].PrintPiece();
      if(!p[i].IsBalance()){
        std::cout << "UNSTABLE" << std::endl;
        break;
      }else if(i == p.size() - 1){
        std::cout << "STABLE" << std::endl;
      }
    }
  }
  return 0;
}

Measured memory_bytes: 1448