#include <bits/stdc++.h>
using namespace std;
using Int = long long;

struct BiconectedGraph{
  typedef pair<Int,int> P;
  Int n;
  vector<vector<Int> > G,C,T;
  vector<Int> ord,low,belong;
  vector<P> B;
  BiconectedGraph(){};
  BiconectedGraph(Int sz):n(sz),G(sz),C(sz),T(sz){};
  
  void add_edge(Int u,Int v){
    G[u].push_back(v);
    G[v].push_back(u);
  }
  

  bool is_bridge(Int u,Int v){
    if(ord[u] > ord[v]) swap(u,v);
    return ord[u] < low[v];
  }

  void dfs(Int u,Int p,Int &k){
    ord[u] = low[u] = k;
    ++k;
    for(Int v:G[u]){
      if(v == p) continue;
      if(ord[v] >=0){
	low[u] = min(low[u],ord[v]);
      } else {
	dfs(v,u,k);
	low[u] = min(low[u],low[v]);
      }
      if(is_bridge(u,v)) B.push_back(P(u,v));
    }
  }
  
  void fill_component(Int c,Int u){
    C[c].push_back(u);
    belong[u] = c;
    for(Int v:G[u]){
      if(belong[v] >= 0 || is_bridge(u,v)) continue;
      fill_component(c,v);
    }
  }
  
  void add_component(Int u,Int &k){
    if(belong[u] >=0) return;
    fill_component(k++,u);
  }
  
  Int build(){
    Int k = 0;
    ord.resize(n);
    low.resize(n);
    belong.resize(n);
    fill(ord.begin(),ord.end(),-1);
    fill(belong.begin(),belong.end(),-1);
    for(Int u=0;u<n;u++){
      if(ord[u] >= 0) continue;
      dfs(u,-1,k);
    }
    k = 0;
    for(Int i=0;i<(Int)B.size();i++){
      add_component(B[i].first,k);
      add_component(B[i].second,k);
    }
    
    for(Int u=0;u<n;u++) add_component(u,k);
    for(Int i=0;i<(Int)B.size();i++){
      Int u = belong[B[i].first], v = belong[B[i].second];
      T[u].push_back(v);
      T[v].push_back(u);
    }
    return k;
  }
};

template <typename T>
vector<T> dijkstra(Int s,vector<vector<pair<Int,T> > > &G,T INF){
  using P = pair<T,Int>;
  Int n = G.size();
  vector<T> d(n,INF);
  vector<Int> b(n,-1);
  priority_queue<P,vector<P>,greater<P> > q;
  d[s] = 0;
  q.emplace(d[s],s);
  while(!q.empty()){
    P p = q.top();q.pop();
    Int v = p.second;
    if(d[v] < p.first) continue;
    for(auto &e:G[v]){
      Int u = e.first;
      T c = e.second;
      if(d[u] > d[v]+c){
	d[u] = d[v] + c;
	b[u] = v;
	q.emplace(d[u],u);
      } 
    }
    
  }
  return d;
}

signed main(){
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n,m;
  cin>>n>>m;
  vector<Int> a(m),b(m),c(m);
  for(Int i=0;i<m;i++) cin>>a[i]>>b[i]>>c[i];
  
  using P = pair<Int, Int>;
  vector<vector<P> > G(n);
  vector<vector<P> > rG(n);
  for(Int i=0;i<m;i++){
    a[i]--;b[i]--;
    G[a[i]].emplace_back(b[i],c[i]);
    rG[b[i]].emplace_back(a[i],c[i]);
  }
  const Int INF = 1e12;
  auto d1=dijkstra(0,G,INF);
  auto d2=dijkstra(1,rG,INF);
  //for(Int i=0;i<n;i++) cout<<"D1:"<<i<<" "<<d1[i]<<endl;
  //for(Int i=0;i<n;i++) cout<<"D2:"<<i<<" "<<d2[i]<<endl;

  vector<Int> used(m,0);
  BiconectedGraph bg(n);
  for(Int i=0;i<m;i++){
    if(d1[a[i]]==INF||d2[b[i]]==INF) continue;
    if(d1[a[i]]+d2[b[i]]+c[i]==d1[1]){
      bg.add_edge(a[i],b[i]);
      used[i]=1;
      //cout<<i<<endl;
    }
  }
  bg.build();
  
  for(Int i=0;i<m;i++){
    if(d1[b[i]]+d2[a[i]]+c[i]<d1[1]){
      cout<<"HAPPY"<<endl;
      continue;
    }
    if(d1[b[i]]+d2[a[i]]+c[i]==d1[1]){
      cout<<"SOSO"<<endl;
      continue;
    }
    if(!used[i]){
      cout<<"SOSO"<<endl;
      continue;
    }
    if(bg.is_bridge(a[i],b[i])) cout<<"SAD"<<endl;
    else cout<<"SOSO"<<endl;
  }
  return 0;
}

