#include <bits/stdc++.h>
using namespace std;
struct initon {
  initon() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout.setf(ios::fixed);
    cout.precision(16);
    srand((unsigned)clock() + (unsigned)time(NULL));
  };
} __initon;
struct T {
  int f, s, t;
  T() { f = -1, s = -1, t = -1; }
  T(int f, int s, int t) : f(f), s(s), t(t) {}
  bool operator<(const T &r) const {
    return f != r.f ? f < r.f : s != r.s ? s < r.s : t < r.t;
  }
  bool operator>(const T &r) const {
    return f != r.f ? f > r.f : s != r.s ? s > r.s : t > r.t;
  }
  bool operator==(const T &r) const { return f == r.f && s == r.s && t == r.t; }
  bool operator!=(const T &r) const { return f != r.f || s != r.s || t != r.t; }
  int operator[](int i) {
    assert(i < 3);
    return i == 0 ? f : i == 1 ? s : t;
  }
};
using dou = long double;
using itn = long long;
using str = string;
using bo = bool;
using P = pair<long long, long long>;
using vi = vector<long long>;
using vl = vector<long long>;
using vb = vector<bool>;
using vs = vector<string>;
using vd = vector<long double>;
using vc = vector<char>;
using vp = vector<P>;
using vt = vector<T>;
using mapi = map<long long, long long>;
using mapd = map<dou, long long>;
using mapc = map<char, long long>;
using maps = map<str, long long>;
using seti = set<long long>;
using setd = set<dou>;
using setc = set<char>;
using sets = set<str>;
using qui = queue<long long>;
const long long inf = (long long)1e9 + 100;
const long long linf = (long long)1e18 + 100;
const long double eps = 1e-9;
const long double PI = 3.1415926535897932384626433832795029L;
long long ma = numeric_limits<long long>::min();
long long mi = numeric_limits<long long>::max();
const long long y4[] = {-1, 1, 0, 0};
const long long x4[] = {0, 0, -1, 1};
const long long y8[] = {0, 1, 0, -1, -1, 1, 1, -1};
const long long x8[] = {1, 0, -1, 0, 1, -1, 1, -1};
inline void sort(string &a) { sort(a.begin(), a.end()); }
template <class T>
inline void sort(vector<T> &a) {
  sort(a.begin(), a.end());
};
template <class T>
inline void sort(vector<T> &a, long long len) {
  sort(a.begin(), a.begin() + len);
};
template <class T, class F>
inline void sort(vector<T> &a, F f) {
  sort(a.begin(), a.end(), [&](T l, T r) { return f(l) < f(r); });
};
enum ___pcomparator { fisi, fisd, fdsi, fdsd, sifi, sifd, sdfi, sdfd };
inline void sort(vector<P> &a, ___pcomparator type) {
  switch (type) {
    case fisi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first < r.first : l.second < r.second;
      });
      break;
    case fisd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first < r.first : l.second > r.second;
      });
      break;
    case fdsi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first > r.first : l.second < r.second;
      });
      break;
    case fdsd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first > r.first : l.second > r.second;
      });
      break;
    case sifi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second < r.second : l.first < r.first;
      });
      break;
    case sifd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second < r.second : l.first > r.first;
      });
      break;
    case sdfi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second > r.second : l.first < r.first;
      });
      break;
    case sdfd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second > r.second : l.first > r.first;
      });
      break;
  }
};
inline void sort(vector<T> &a, ___pcomparator type) {
  switch (type) {
    case fisi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f < r.f : l.s < r.s; });
      break;
    case fisd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f < r.f : l.s > r.s; });
      break;
    case fdsi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f > r.f : l.s < r.s; });
      break;
    case fdsd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f > r.f : l.s > r.s; });
      break;
    case sifi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s < r.s : l.f < r.f; });
      break;
    case sifd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s < r.s : l.f > r.f; });
      break;
    case sdfi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s > r.s : l.f < r.f; });
      break;
    case sdfd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s > r.s : l.f > r.f; });
      break;
  }
};
template <class T>
inline void rsort(vector<T> &a) {
  sort(a.begin(), a.end(), greater<T>());
};
template <class T>
inline void rsort(vector<T> &a, long long len) {
  sort(a.begin(), a.begin() + len, greater<T>());
};
template <class U, class F>
inline void rsort(vector<U> &a, F f) {
  sort(a.begin(), a.end(), [&](U l, U r) { return f(l) > f(r); });
};
template <class U>
inline void sortp(vector<U> &a, vector<U> &b) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  sort(c);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
    ;
  }
};
template <class U, class F>
inline void sortp(vector<U> &a, vector<U> &b, F f) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  sort(c, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U, class F>
inline void sortp(vector<U> &a, vector<U> &b, char type) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  sort(c, type);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U>
inline void rsortp(vector<U> &a, vector<U> &b) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  rsort(c);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U, class F>
inline void rsortp(vector<U> &a, vector<U> &b, F f) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  rsort(c, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U>
inline void sortt(vector<U> &a, vector<U> &b, vector<U> &c) {
  vt r;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  assert(n == ((long long)(c).size()));
  for (long long i = 0, _lim = n; i < _lim; i++)
    r.emplace_back(a[i], b[i], c[i]);
  sort(r);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = r[i].f;
    b[i] = r[i].s;
    c[i] = r[i].t;
  }
};
template <class U, class F>
inline void sortt(vector<U> &a, vector<U> &b, vector<U> &c, F f) {
  vt r;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  assert(n == ((long long)(c).size()));
  for (long long i = 0, _lim = n; i < _lim; i++)
    r.emplace_back(a[i], b[i], c[i]);
  sort(r, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = r[i].f;
    b[i] = r[i].s;
    c[i] = r[i].t;
  }
};
template <class U, class F>
inline void rsortt(vector<U> &a, vector<U> &b, vector<U> &c, F f) {
  vt r;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  assert(n == ((long long)(c).size()));
  for (long long i = 0, _lim = n; i < _lim; i++)
    r.emplace_back(a[i], b[i], c[i]);
  rsort(r, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = r[i].f;
    b[i] = r[i].s;
    c[i] = r[i].t;
  }
};
template <class T>
inline void sort2(vector<vector<T>> &a) {
  for (long long i = 0, n = a.size(); i < n; i++) sort(a[i]);
}
template <class T>
inline void rsort2(vector<vector<T>> &a) {
  for (long long i = 0, n = a.size(); i < n; i++) rsort(a[i]);
}
template <typename A, size_t N, typename T>
void fill(A (&a)[N], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++) a[i] = v;
}
template <typename A, size_t N, size_t O, typename T>
void fill(A (&a)[N][O], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++) a[i][j] = v;
}
template <typename A, size_t N, size_t O, size_t P, typename T>
void fill(A (&a)[N][O][P], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++) a[i][j][k] = v;
}
template <typename A, size_t N, size_t O, size_t P, size_t Q, typename T>
void fill(A (&a)[N][O][P][Q], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++)
        for (long long l = 0, _lim = Q; l < _lim; l++) a[i][j][k][l] = v;
}
template <typename A, size_t N, size_t O, size_t P, size_t Q, size_t R,
          typename T>
void fill(A (&a)[N][O][P][Q][R], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++)
        for (long long l = 0, _lim = Q; l < _lim; l++)
          for (long long m = 0, _lim = R; m < _lim; m++) a[i][j][k][l][m] = v;
}
template <typename A, size_t N, size_t O, size_t P, size_t Q, size_t R,
          size_t S, typename T>
void fill(A (&a)[N][O][P][Q][R][S], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++)
        for (long long l = 0, _lim = Q; l < _lim; l++)
          for (long long m = 0, _lim = R; m < _lim; m++)
            for (long long n = 0, _lim = S; n < _lim; n++)
              a[i][j][k][l][m][n] = v;
}
template <typename V, typename T>
void fill(V &xx, const T vall) {
  xx = vall;
}
template <typename V, typename T>
void fill(vector<V> &vecc, const T vall) {
  for (auto &&vx : vecc) fill(vx, vall);
}
template <typename T = long long>
T _in() {
  T x;
  cin >> x;
  return (x);
}
string sin() { return _in<string>(); }
long long lin() { return _in<long long>(); }
void ole() {
  string a = "a";
  for (long long i = 0, _lim = 30; i < _lim; i++) a += a;
  for (long long i = 0, _lim = 1 << 17; i < _lim; i++) cout << a << endl;
  cout << "OLE 出力長制限超過" << endl;
  exit(0);
}
void tle() {
  while (inf) cout << inf << endl;
}
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
long long gcd(vi b) {
  long long res = b[0];
  for (auto &&v : b) res = gcd(v, res);
  return res;
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
long long rev(long long a) {
  long long res = 0;
  while (a) {
    res *= 10;
    res += a % 10;
    a /= 10;
  }
  return res;
}
template <class T>
void rev(vector<T> &a) {
  reverse((a).begin(), (a).end());
}
void rev(string &a) { reverse((a).begin(), (a).end()); }
long long ceil(long long a, long long b) {
  if (b == 0) {
    cerr << "ceil"
         << " "
         << "(L:" << 595 << ")" << '\n';
    cerr << "a"
         << " = " << a << ", "
         << "b"
         << " = " << b << endl;
    ole();
    return -1;
  } else
    return (a + b - 1) / b;
}
long long sqrt(long long a) {
  if (a < 0) {
    cerr << "sqrt"
         << " "
         << "(L:" << 604 << ")" << '\n';
    cerr << "a"
         << " = " << a << endl;
    ole();
  }
  long long res = (long long)std::sqrt(a);
  while (res * res < a) res++;
  return res;
}
long double log(long double e, long double x) { return log(x) / log(e); }
long long sig(long long t) { return (1 + t) * t / 2; }
long long sig(long long s, long long t) { return (s + t) * (t - s + 1) / 2; }
vi divisors(long long v) {
  vi res;
  long double lim = std::sqrt(v);
  for (long long i = 1; i <= lim; ++i) {
    if (v % i == 0) {
      res.push_back(i);
      if (i != v / i) res.push_back(v / i);
    }
  }
  return res;
}
vb isPrime;
vi primes;
void setPrime() {
  long long len = 4010101;
  isPrime.resize(4010101);
  fill(isPrime, true);
  isPrime[0] = isPrime[1] = false;
  for (long long i = 2; i <= sqrt(len) + 5; ++i) {
    if (!isPrime[i]) continue;
    for (long long j = 2; i * j < len; ++j) {
      isPrime[i * j] = false;
    }
  }
  for (long long i = 0, _lim = len; i < _lim; i++)
    if (isPrime[i]) primes.push_back(i);
}
vi factorization(long long v) {
  long long tv = v;
  vi res;
  if (isPrime.size() == 0) setPrime();
  for (auto &&p : primes) {
    if (v % p == 0) res.push_back(p);
    while (v % p == 0) {
      v /= p;
    }
    if (v == 1 || p * p > tv) break;
  }
  if (v > 1) res.push_back(v);
  return res;
}
inline bool inside(long long h, long long w, long long H, long long W) {
  return h >= 0 && w >= 0 && h < H && w < W;
}
inline bool inside(long long v, long long l, long long r) {
  return l <= v && v < r;
}
long long u(long long a) { return a < 0 ? 0 : a; }
template <class T>
vector<T> u(const vector<T> &a) {
  vector<T> ret = a;
  for (auto &&v : ret) v = u(v);
  return ret;
}
void yn(bool a) {
  if (a)
    cout << "yes" << endl;
  else
    cout << "no" << endl;
}
void Yn(bool a) {
  if (a)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}
void YN(bool a) {
  if (a)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}
void fyn(bool a) {
  if (a)
    cout << "yes" << endl;
  else
    cout << "no" << endl;
  exit(0);
}
void fYn(bool a) {
  if (a)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
  exit(0);
}
void fYN(bool a) {
  if (a)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
  exit(0);
}
void Possible(bool a) {
  if (a)
    cout << "Possible" << endl;
  else
    cout << "Impossible" << endl;
  exit(0);
}
void POSSIBLE(bool a) {
  if (a)
    cout << "POSSIBLE" << endl;
  else
    cout << "IMPOSSIBLE" << endl;
  exit(0);
}
template <class T, class U>
set<T> &operator+=(set<T> &a, U v) {
  a.insert(v);
  return a;
}
template <class T, class U>
vector<T> &operator+=(vector<T> &a, U v) {
  a.push_back(v);
  return a;
}
template <class T>
T sum(vector<T> &v, long long s = 0, long long t = inf) {
  T ret = 0;
  for (long long i = s, _lim = min(((long long)(v).size()), t); i < _lim; i++)
    ret += v[i];
  return ret;
}
void mod(long long &a, long long m) { a = (a % m + m) % m; }
template <class F>
inline long long mgr(long long ok, long long ng, F f) {
  if (ok < ng)
    while (ng - ok > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid))
        ok = mid;
      else
        ng = mid;
    }
  else
    while (ok - ng > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid))
        ok = mid;
      else
        ng = mid;
    }
  return ok;
}
template <class F>
inline long long mgr(long long ok, long long ng, long long second, F f) {
  if (ok < ng)
    while (ng - ok > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid, second))
        ok = mid;
      else
        ng = mid;
    }
  else
    while (ok - ng > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid, second))
        ok = mid;
      else
        ng = mid;
    }
  return ok;
}
template <typename T>
ostream &operator<<(ostream &os, vector<T> &m) {
  for (auto &&v : m) os << v << " ";
  return os;
}
constexpr bool bget(long long m, long long keta) { return (m >> keta) & 1; }
long long bget(long long m, long long keta, long long sinsuu) {
  m /= (long long)pow(sinsuu, keta);
  return m % sinsuu;
}
long long bit(long long n) { return (1LL << (n)); }
long long bit(long long n, long long sinsuu) {
  return (long long)pow(sinsuu, n);
}
long long mask(long long n) { return (1ll << n) - 1; }
template <class T>
vector<T> ruiv(vector<T> &a) {
  vector<T> ret(a.size() + 1);
  for (long long i = 0, _lim = a.size(); i < _lim; i++)
    ret[i + 1] = ret[i] + a[i];
  return ret;
}
template <class T, class U>
inline bool chma(T &a, const U &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class U>
inline bool chma(const U &b) {
  return chma(ma, b);
}
template <class T, class U>
inline bool chmi(T &a, const U &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
template <class U>
inline bool chmi(const U &b) {
  return chmi(mi, b);
}
long long n, m, k, d, H, W, x, y, z, q;
long long cou;
vi a, b, c;
vector<vi> s(0, vi(0));
vector<vc> ba(0, vc(0));
vp p;
signed main() {
  cin >> n >> q;
  a.resize(n);
  for (long long i = 0, _lim = n; i < _lim; i++) cin >> a[i];
  ;
  vi nx(20, inf);
  vector<vi> canr(n + 1, vi(20, inf));
  for (long long i = n - 1; i >= 0; i--) {
    for (long long b = 0, _lim = 20; b < _lim; b++) {
      if (bget(a[i], b) == 0) continue;
      long long t = nx[b];
      if (t == inf) continue;
      for (long long c = 0, _lim = 20; c < _lim; c++) {
        chmi(canr[i][c], canr[t][c]);
      }
    }
    for (long long b = 0, _lim = 20; b < _lim; b++) {
      if (bget(a[i], b)) {
        nx[b] = i;
        chmi(canr[i][b], i);
      }
    }
  }
  while (q--) {
    long long x, y;
    cin >> x >> y;
    x--, y--;
    bool ok = 0;
    for (long long b = 0, _lim = 20; b < _lim; b++) {
      if (bget(a[y], b) && canr[x][b] <= y) ok = 1;
    }
    if (ok)
      cout << "Shi" << endl;
    else
      cout << "Fou" << endl;
  }
  return 0;
}

### Prompt

Please create a solution in Cpp to the following problem:

Toad Pimple has an array of integers a_1, a_2, …, a_n.

We say that y is reachable from x if x<y and there exists an integer array p such that x = p_1 < p_2 < … < p_k=y, and a_{p_i}  \&  a_{p_{i+1}} > 0 for all integers i such that 1 ≤ i < k.

Here \& denotes the [bitwise AND operation](https://en.wikipedia.org/wiki/Bitwise_operation#AND).

You are given q pairs of indices, check reachability for each of them.

Input

The first line contains two integers n and q (2 ≤ n ≤ 300 000, 1 ≤ q ≤ 300 000) — the number of integers in the array and the number of queries you need to answer.

The second line contains n space-separated integers a_1, a_2, …, a_n (0 ≤ a_i ≤ 300 000) — the given array.

The next q lines contain two integers each. The i-th of them contains two space-separated integers x_i and y_i (1 ≤ x_i < y_i ≤ n). You need to check if y_i is reachable from x_i. 

Output

Output q lines. In the i-th of them print "Shi" if y_i is reachable from x_i, otherwise, print "Fou".

Example

Input


5 3
1 3 0 2 1
1 3
2 4
1 4


Output


Fou
Shi
Shi

Note

In the first example, a_3 = 0. You can't reach it, because AND with it is always zero. a_2  \&  a_4 > 0, so 4 is reachable from 2, and to go from 1 to 4 you can use p = [1, 2, 4].

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
struct initon {
  initon() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout.setf(ios::fixed);
    cout.precision(16);
    srand((unsigned)clock() + (unsigned)time(NULL));
  };
} __initon;
struct T {
  int f, s, t;
  T() { f = -1, s = -1, t = -1; }
  T(int f, int s, int t) : f(f), s(s), t(t) {}
  bool operator<(const T &r) const {
    return f != r.f ? f < r.f : s != r.s ? s < r.s : t < r.t;
  }
  bool operator>(const T &r) const {
    return f != r.f ? f > r.f : s != r.s ? s > r.s : t > r.t;
  }
  bool operator==(const T &r) const { return f == r.f && s == r.s && t == r.t; }
  bool operator!=(const T &r) const { return f != r.f || s != r.s || t != r.t; }
  int operator[](int i) {
    assert(i < 3);
    return i == 0 ? f : i == 1 ? s : t;
  }
};
using dou = long double;
using itn = long long;
using str = string;
using bo = bool;
using P = pair<long long, long long>;
using vi = vector<long long>;
using vl = vector<long long>;
using vb = vector<bool>;
using vs = vector<string>;
using vd = vector<long double>;
using vc = vector<char>;
using vp = vector<P>;
using vt = vector<T>;
using mapi = map<long long, long long>;
using mapd = map<dou, long long>;
using mapc = map<char, long long>;
using maps = map<str, long long>;
using seti = set<long long>;
using setd = set<dou>;
using setc = set<char>;
using sets = set<str>;
using qui = queue<long long>;
const long long inf = (long long)1e9 + 100;
const long long linf = (long long)1e18 + 100;
const long double eps = 1e-9;
const long double PI = 3.1415926535897932384626433832795029L;
long long ma = numeric_limits<long long>::min();
long long mi = numeric_limits<long long>::max();
const long long y4[] = {-1, 1, 0, 0};
const long long x4[] = {0, 0, -1, 1};
const long long y8[] = {0, 1, 0, -1, -1, 1, 1, -1};
const long long x8[] = {1, 0, -1, 0, 1, -1, 1, -1};
inline void sort(string &a) { sort(a.begin(), a.end()); }
template <class T>
inline void sort(vector<T> &a) {
  sort(a.begin(), a.end());
};
template <class T>
inline void sort(vector<T> &a, long long len) {
  sort(a.begin(), a.begin() + len);
};
template <class T, class F>
inline void sort(vector<T> &a, F f) {
  sort(a.begin(), a.end(), [&](T l, T r) { return f(l) < f(r); });
};
enum ___pcomparator { fisi, fisd, fdsi, fdsd, sifi, sifd, sdfi, sdfd };
inline void sort(vector<P> &a, ___pcomparator type) {
  switch (type) {
    case fisi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first < r.first : l.second < r.second;
      });
      break;
    case fisd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first < r.first : l.second > r.second;
      });
      break;
    case fdsi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first > r.first : l.second < r.second;
      });
      break;
    case fdsd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.first != r.first ? l.first > r.first : l.second > r.second;
      });
      break;
    case sifi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second < r.second : l.first < r.first;
      });
      break;
    case sifd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second < r.second : l.first > r.first;
      });
      break;
    case sdfi:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second > r.second : l.first < r.first;
      });
      break;
    case sdfd:
      sort((a).begin(), (a).end(), [&](P l, P r) {
        return l.second != r.second ? l.second > r.second : l.first > r.first;
      });
      break;
  }
};
inline void sort(vector<T> &a, ___pcomparator type) {
  switch (type) {
    case fisi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f < r.f : l.s < r.s; });
      break;
    case fisd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f < r.f : l.s > r.s; });
      break;
    case fdsi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f > r.f : l.s < r.s; });
      break;
    case fdsd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.f != r.f ? l.f > r.f : l.s > r.s; });
      break;
    case sifi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s < r.s : l.f < r.f; });
      break;
    case sifd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s < r.s : l.f > r.f; });
      break;
    case sdfi:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s > r.s : l.f < r.f; });
      break;
    case sdfd:
      sort((a).begin(), (a).end(),
           [&](T l, T r) { return l.s != r.s ? l.s > r.s : l.f > r.f; });
      break;
  }
};
template <class T>
inline void rsort(vector<T> &a) {
  sort(a.begin(), a.end(), greater<T>());
};
template <class T>
inline void rsort(vector<T> &a, long long len) {
  sort(a.begin(), a.begin() + len, greater<T>());
};
template <class U, class F>
inline void rsort(vector<U> &a, F f) {
  sort(a.begin(), a.end(), [&](U l, U r) { return f(l) > f(r); });
};
template <class U>
inline void sortp(vector<U> &a, vector<U> &b) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  sort(c);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
    ;
  }
};
template <class U, class F>
inline void sortp(vector<U> &a, vector<U> &b, F f) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  sort(c, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U, class F>
inline void sortp(vector<U> &a, vector<U> &b, char type) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  sort(c, type);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U>
inline void rsortp(vector<U> &a, vector<U> &b) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  rsort(c);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U, class F>
inline void rsortp(vector<U> &a, vector<U> &b, F f) {
  vp c;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  for (long long i = 0, _lim = n; i < _lim; i++) c.emplace_back(a[i], b[i]);
  rsort(c, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = c[i].first;
    b[i] = c[i].second;
  }
};
template <class U>
inline void sortt(vector<U> &a, vector<U> &b, vector<U> &c) {
  vt r;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  assert(n == ((long long)(c).size()));
  for (long long i = 0, _lim = n; i < _lim; i++)
    r.emplace_back(a[i], b[i], c[i]);
  sort(r);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = r[i].f;
    b[i] = r[i].s;
    c[i] = r[i].t;
  }
};
template <class U, class F>
inline void sortt(vector<U> &a, vector<U> &b, vector<U> &c, F f) {
  vt r;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  assert(n == ((long long)(c).size()));
  for (long long i = 0, _lim = n; i < _lim; i++)
    r.emplace_back(a[i], b[i], c[i]);
  sort(r, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = r[i].f;
    b[i] = r[i].s;
    c[i] = r[i].t;
  }
};
template <class U, class F>
inline void rsortt(vector<U> &a, vector<U> &b, vector<U> &c, F f) {
  vt r;
  long long n = ((long long)(a).size());
  assert(n == ((long long)(b).size()));
  assert(n == ((long long)(c).size()));
  for (long long i = 0, _lim = n; i < _lim; i++)
    r.emplace_back(a[i], b[i], c[i]);
  rsort(r, f);
  for (long long i = 0, _lim = n; i < _lim; i++) {
    a[i] = r[i].f;
    b[i] = r[i].s;
    c[i] = r[i].t;
  }
};
template <class T>
inline void sort2(vector<vector<T>> &a) {
  for (long long i = 0, n = a.size(); i < n; i++) sort(a[i]);
}
template <class T>
inline void rsort2(vector<vector<T>> &a) {
  for (long long i = 0, n = a.size(); i < n; i++) rsort(a[i]);
}
template <typename A, size_t N, typename T>
void fill(A (&a)[N], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++) a[i] = v;
}
template <typename A, size_t N, size_t O, typename T>
void fill(A (&a)[N][O], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++) a[i][j] = v;
}
template <typename A, size_t N, size_t O, size_t P, typename T>
void fill(A (&a)[N][O][P], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++) a[i][j][k] = v;
}
template <typename A, size_t N, size_t O, size_t P, size_t Q, typename T>
void fill(A (&a)[N][O][P][Q], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++)
        for (long long l = 0, _lim = Q; l < _lim; l++) a[i][j][k][l] = v;
}
template <typename A, size_t N, size_t O, size_t P, size_t Q, size_t R,
          typename T>
void fill(A (&a)[N][O][P][Q][R], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++)
        for (long long l = 0, _lim = Q; l < _lim; l++)
          for (long long m = 0, _lim = R; m < _lim; m++) a[i][j][k][l][m] = v;
}
template <typename A, size_t N, size_t O, size_t P, size_t Q, size_t R,
          size_t S, typename T>
void fill(A (&a)[N][O][P][Q][R][S], const T &v) {
  for (long long i = 0, _lim = N; i < _lim; i++)
    for (long long j = 0, _lim = O; j < _lim; j++)
      for (long long k = 0, _lim = P; k < _lim; k++)
        for (long long l = 0, _lim = Q; l < _lim; l++)
          for (long long m = 0, _lim = R; m < _lim; m++)
            for (long long n = 0, _lim = S; n < _lim; n++)
              a[i][j][k][l][m][n] = v;
}
template <typename V, typename T>
void fill(V &xx, const T vall) {
  xx = vall;
}
template <typename V, typename T>
void fill(vector<V> &vecc, const T vall) {
  for (auto &&vx : vecc) fill(vx, vall);
}
template <typename T = long long>
T _in() {
  T x;
  cin >> x;
  return (x);
}
string sin() { return _in<string>(); }
long long lin() { return _in<long long>(); }
void ole() {
  string a = "a";
  for (long long i = 0, _lim = 30; i < _lim; i++) a += a;
  for (long long i = 0, _lim = 1 << 17; i < _lim; i++) cout << a << endl;
  cout << "OLE 出力長制限超過" << endl;
  exit(0);
}
void tle() {
  while (inf) cout << inf << endl;
}
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
long long gcd(vi b) {
  long long res = b[0];
  for (auto &&v : b) res = gcd(v, res);
  return res;
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
long long rev(long long a) {
  long long res = 0;
  while (a) {
    res *= 10;
    res += a % 10;
    a /= 10;
  }
  return res;
}
template <class T>
void rev(vector<T> &a) {
  reverse((a).begin(), (a).end());
}
void rev(string &a) { reverse((a).begin(), (a).end()); }
long long ceil(long long a, long long b) {
  if (b == 0) {
    cerr << "ceil"
         << " "
         << "(L:" << 595 << ")" << '\n';
    cerr << "a"
         << " = " << a << ", "
         << "b"
         << " = " << b << endl;
    ole();
    return -1;
  } else
    return (a + b - 1) / b;
}
long long sqrt(long long a) {
  if (a < 0) {
    cerr << "sqrt"
         << " "
         << "(L:" << 604 << ")" << '\n';
    cerr << "a"
         << " = " << a << endl;
    ole();
  }
  long long res = (long long)std::sqrt(a);
  while (res * res < a) res++;
  return res;
}
long double log(long double e, long double x) { return log(x) / log(e); }
long long sig(long long t) { return (1 + t) * t / 2; }
long long sig(long long s, long long t) { return (s + t) * (t - s + 1) / 2; }
vi divisors(long long v) {
  vi res;
  long double lim = std::sqrt(v);
  for (long long i = 1; i <= lim; ++i) {
    if (v % i == 0) {
      res.push_back(i);
      if (i != v / i) res.push_back(v / i);
    }
  }
  return res;
}
vb isPrime;
vi primes;
void setPrime() {
  long long len = 4010101;
  isPrime.resize(4010101);
  fill(isPrime, true);
  isPrime[0] = isPrime[1] = false;
  for (long long i = 2; i <= sqrt(len) + 5; ++i) {
    if (!isPrime[i]) continue;
    for (long long j = 2; i * j < len; ++j) {
      isPrime[i * j] = false;
    }
  }
  for (long long i = 0, _lim = len; i < _lim; i++)
    if (isPrime[i]) primes.push_back(i);
}
vi factorization(long long v) {
  long long tv = v;
  vi res;
  if (isPrime.size() == 0) setPrime();
  for (auto &&p : primes) {
    if (v % p == 0) res.push_back(p);
    while (v % p == 0) {
      v /= p;
    }
    if (v == 1 || p * p > tv) break;
  }
  if (v > 1) res.push_back(v);
  return res;
}
inline bool inside(long long h, long long w, long long H, long long W) {
  return h >= 0 && w >= 0 && h < H && w < W;
}
inline bool inside(long long v, long long l, long long r) {
  return l <= v && v < r;
}
long long u(long long a) { return a < 0 ? 0 : a; }
template <class T>
vector<T> u(const vector<T> &a) {
  vector<T> ret = a;
  for (auto &&v : ret) v = u(v);
  return ret;
}
void yn(bool a) {
  if (a)
    cout << "yes" << endl;
  else
    cout << "no" << endl;
}
void Yn(bool a) {
  if (a)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
}
void YN(bool a) {
  if (a)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
}
void fyn(bool a) {
  if (a)
    cout << "yes" << endl;
  else
    cout << "no" << endl;
  exit(0);
}
void fYn(bool a) {
  if (a)
    cout << "Yes" << endl;
  else
    cout << "No" << endl;
  exit(0);
}
void fYN(bool a) {
  if (a)
    cout << "YES" << endl;
  else
    cout << "NO" << endl;
  exit(0);
}
void Possible(bool a) {
  if (a)
    cout << "Possible" << endl;
  else
    cout << "Impossible" << endl;
  exit(0);
}
void POSSIBLE(bool a) {
  if (a)
    cout << "POSSIBLE" << endl;
  else
    cout << "IMPOSSIBLE" << endl;
  exit(0);
}
template <class T, class U>
set<T> &operator+=(set<T> &a, U v) {
  a.insert(v);
  return a;
}
template <class T, class U>
vector<T> &operator+=(vector<T> &a, U v) {
  a.push_back(v);
  return a;
}
template <class T>
T sum(vector<T> &v, long long s = 0, long long t = inf) {
  T ret = 0;
  for (long long i = s, _lim = min(((long long)(v).size()), t); i < _lim; i++)
    ret += v[i];
  return ret;
}
void mod(long long &a, long long m) { a = (a % m + m) % m; }
template <class F>
inline long long mgr(long long ok, long long ng, F f) {
  if (ok < ng)
    while (ng - ok > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid))
        ok = mid;
      else
        ng = mid;
    }
  else
    while (ok - ng > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid))
        ok = mid;
      else
        ng = mid;
    }
  return ok;
}
template <class F>
inline long long mgr(long long ok, long long ng, long long second, F f) {
  if (ok < ng)
    while (ng - ok > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid, second))
        ok = mid;
      else
        ng = mid;
    }
  else
    while (ok - ng > 1) {
      long long mid = (ok + ng) / 2;
      if (f(mid, second))
        ok = mid;
      else
        ng = mid;
    }
  return ok;
}
template <typename T>
ostream &operator<<(ostream &os, vector<T> &m) {
  for (auto &&v : m) os << v << " ";
  return os;
}
constexpr bool bget(long long m, long long keta) { return (m >> keta) & 1; }
long long bget(long long m, long long keta, long long sinsuu) {
  m /= (long long)pow(sinsuu, keta);
  return m % sinsuu;
}
long long bit(long long n) { return (1LL << (n)); }
long long bit(long long n, long long sinsuu) {
  return (long long)pow(sinsuu, n);
}
long long mask(long long n) { return (1ll << n) - 1; }
template <class T>
vector<T> ruiv(vector<T> &a) {
  vector<T> ret(a.size() + 1);
  for (long long i = 0, _lim = a.size(); i < _lim; i++)
    ret[i + 1] = ret[i] + a[i];
  return ret;
}
template <class T, class U>
inline bool chma(T &a, const U &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class U>
inline bool chma(const U &b) {
  return chma(ma, b);
}
template <class T, class U>
inline bool chmi(T &a, const U &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}
template <class U>
inline bool chmi(const U &b) {
  return chmi(mi, b);
}
long long n, m, k, d, H, W, x, y, z, q;
long long cou;
vi a, b, c;
vector<vi> s(0, vi(0));
vector<vc> ba(0, vc(0));
vp p;
signed main() {
  cin >> n >> q;
  a.resize(n);
  for (long long i = 0, _lim = n; i < _lim; i++) cin >> a[i];
  ;
  vi nx(20, inf);
  vector<vi> canr(n + 1, vi(20, inf));
  for (long long i = n - 1; i >= 0; i--) {
    for (long long b = 0, _lim = 20; b < _lim; b++) {
      if (bget(a[i], b) == 0) continue;
      long long t = nx[b];
      if (t == inf) continue;
      for (long long c = 0, _lim = 20; c < _lim; c++) {
        chmi(canr[i][c], canr[t][c]);
      }
    }
    for (long long b = 0, _lim = 20; b < _lim; b++) {
      if (bget(a[i], b)) {
        nx[b] = i;
        chmi(canr[i][b], i);
      }
    }
  }
  while (q--) {
    long long x, y;
    cin >> x >> y;
    x--, y--;
    bool ok = 0;
    for (long long b = 0, _lim = 20; b < _lim; b++) {
      if (bget(a[y], b) && canr[x][b] <= y) ok = 1;
    }
    if (ok)
      cout << "Shi" << endl;
    else
      cout << "Fou" << endl;
  }
  return 0;
}

```