#include <bits/stdc++.h>
using namespace std;
long long rdtsc() {
  long long tmp;
  asm("rdtsc" : "=A"(tmp));
  return tmp;
}
inline int myrand() { return abs((rand() << 15) ^ rand()); }
inline int rnd(int x) { return myrand() % x; }
struct Info {
  int mask;
  int value;
  Info() {}
  Info(int left, int right, int l) : value(0) {
    mask = 0;
    for (int i = 0; i < l; ++i)
      if ((right / (1 << i) - left / (1 << i)) & 1) mask ^= (1 << i);
  }
  Info(const Info &left, const Info &right) {
    value = min(left.value, right.value);
    mask = 0;
    if (left.value == value) mask ^= left.mask;
    if (right.value == value) mask ^= right.mask;
  }
};
struct NodeInfo {
  int toadd;
  Info info;
  NodeInfo() {}
  NodeInfo(int _toadd, const Info &_info) : toadd(_toadd), info(_info) {}
};
struct SegmTree {
  const static int maxn = (1 << 17);
  NodeInfo a[2 * maxn];
  int n;
  int wholeMask;
  void build(int cnt, int *xs, int l) {
    for (n = 1; n < cnt; n <<= 1)
      ;
    wholeMask = 0;
    for (int i = 0; i < n; ++i) {
      if (i < cnt - 1)
        a[i + n] = NodeInfo(0, Info(xs[i], xs[i + 1], l));
      else
        a[i + n] = NodeInfo(0, Info(0, 0, l));
      wholeMask ^= a[i + n].info.mask;
    }
    for (int i = n - 1; i; --i)
      a[i] = NodeInfo(0, Info(a[2 * i].info, a[2 * i + 1].info));
  }
  void push(int v) {
    if (a[v].toadd == 0) return;
    a[2 * v].toadd += a[v].toadd;
    a[2 * v].info.value += a[v].toadd;
    a[2 * v + 1].toadd += a[v].toadd;
    a[2 * v + 1].info.value += a[v].toadd;
    a[v].toadd = 0;
  }
  void update(int v) {
    a[v] = NodeInfo(0, Info(a[2 * v].info, a[2 * v + 1].info));
  }
  void add(int v, int l, int r, int l0, int r0, int toadd) {
    if (l >= r0 || l0 >= r) return;
    if (l0 <= l && r <= r0) {
      a[v].toadd += toadd;
      a[v].info.value += toadd;
      return;
    }
    push(v);
    int m = (l + r) / 2;
    add(2 * v, l, m, l0, r0, toadd);
    add(2 * v + 1, m, r, l0, r0, toadd);
    update(v);
  }
  void add(int l, int r, int toadd) { add(1, 0, n, l, r, toadd); }
  int getVal() const {
    assert(a[1].info.value == 0);
    return wholeMask ^ a[1].info.mask;
  }
} tree;
int l;
struct Event {
  int type, x, l, r;
  Event() {}
  Event(int _type, int _x, int _l, int _r) : type(_type), x(_x), l(_l), r(_r) {}
  inline bool operator<(const Event &e) const {
    if (x != e.x) return x < e.x;
    return 0;
  }
};
const int maxn = (int)1e5 + 10;
Event evs[maxn];
int xs[maxn];
bool solve() {
  int n, m, k;
  if (scanf("%d%d%d", &n, &m, &k) < 2) return 0;
  int res = 0;
  l = 0;
  for (; (1 << l) <= k; ++l)
    ;
  int cnt = 0;
  for (int i = 0; i < m; ++i) {
    int a, b, c, d;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    --a, --b;
    evs[2 * i] = Event(0, a, b, d);
    evs[2 * i + 1] = Event(1, c, b, d);
    xs[cnt++] = b;
    xs[cnt++] = d;
  }
  sort(evs, evs + 2 * m);
  sort(xs, xs + cnt);
  cnt = unique(xs, xs + cnt) - xs;
  for (int i = 0; i < 2 * m; ++i) {
    evs[i].l = lower_bound(xs, xs + cnt, evs[i].l) - xs;
    evs[i].r = lower_bound(xs, xs + cnt, evs[i].r) - xs;
  }
  tree.build(cnt, xs, l);
  for (int i = 0; i < 2 * m; ++i) {
    Event &cur = evs[i];
    if (i > 0) {
      Info info(evs[i].x, evs[i - 1].x, l);
      int val = tree.getVal();
      for (int it = 0; it < l; ++it) {
        if (((info.mask >> it) & 1) && ((val >> it) & 1)) {
          res ^= (1 << it);
          res ^= (1 << it) / 2;
        }
      }
    }
    tree.add(cur.l, cur.r, !cur.type ? 1 : -1);
  }
  printf(res ? "Hamed\n" : "Malek\n");
  return 1;
}
int main() {
  srand(rdtsc());
  while (1) {
    if (!solve()) break;
  }
  return 0;
}

### Prompt

Develop a solution in CPP to the problem described below:

During the last 24 hours Hamed and Malek spent all their time playing "Sharti". Now they are too exhausted to finish the last round. So they asked you for help to determine the winner of this round. 

"Sharti" is played on a n × n board with some of cells colored white and others colored black. The rows of the board are numbered from top to bottom using number 1 to n. Also the columns of the board are numbered from left to right using numbers 1 to n. The cell located at the intersection of i-th row and j-th column is denoted by (i, j).

The players alternatively take turns. In each turn the player must choose a square with side-length at most k with its lower-right cell painted white. Then the colors of all the cells in this square are inversed (white cells become black and vice-versa). The player who cannot perform a move in his turn loses. 

You know Hamed and Malek are very clever and they would have played their best moves at each turn. Knowing this and the fact that Hamed takes the first turn, given the initial board as described in the input, you must determine which one of them will be the winner.

Input

In this problem the initial board is specified as a set of m rectangles. All cells that lie inside at least one of these rectangles are colored white and the rest are colored black.

In the first line of input three space-spereated integers n, m, k (1 ≤ k ≤ n ≤ 109, 1 ≤ m ≤ 5·104) follow, denoting size of the board, number of rectangles and maximum size of the turn square during the game, respectively.

In i-th line of the next m lines four space-seperated integers ai, bi, ci, di (1 ≤ ai ≤ ci ≤ n, 1 ≤ bi ≤ di ≤ n) are given meaning that i-th rectangle determining the initial board is a rectangle with upper-left cell at (ai, bi) and lower-right cell at (ci, di).

Output

If Hamed wins, print "Hamed", otherwise print "Malek" (without the quotes).

Examples

Input

5 2 1
1 1 3 3
2 2 4 4


Output

Malek


Input

12 5 7
3 4 5 6
1 2 1 2
4 5 9 9
8 6 12 10
12 4 12 4


Output

Hamed

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;
long long rdtsc() {
  long long tmp;
  asm("rdtsc" : "=A"(tmp));
  return tmp;
}
inline int myrand() { return abs((rand() << 15) ^ rand()); }
inline int rnd(int x) { return myrand() % x; }
struct Info {
  int mask;
  int value;
  Info() {}
  Info(int left, int right, int l) : value(0) {
    mask = 0;
    for (int i = 0; i < l; ++i)
      if ((right / (1 << i) - left / (1 << i)) & 1) mask ^= (1 << i);
  }
  Info(const Info &left, const Info &right) {
    value = min(left.value, right.value);
    mask = 0;
    if (left.value == value) mask ^= left.mask;
    if (right.value == value) mask ^= right.mask;
  }
};
struct NodeInfo {
  int toadd;
  Info info;
  NodeInfo() {}
  NodeInfo(int _toadd, const Info &_info) : toadd(_toadd), info(_info) {}
};
struct SegmTree {
  const static int maxn = (1 << 17);
  NodeInfo a[2 * maxn];
  int n;
  int wholeMask;
  void build(int cnt, int *xs, int l) {
    for (n = 1; n < cnt; n <<= 1)
      ;
    wholeMask = 0;
    for (int i = 0; i < n; ++i) {
      if (i < cnt - 1)
        a[i + n] = NodeInfo(0, Info(xs[i], xs[i + 1], l));
      else
        a[i + n] = NodeInfo(0, Info(0, 0, l));
      wholeMask ^= a[i + n].info.mask;
    }
    for (int i = n - 1; i; --i)
      a[i] = NodeInfo(0, Info(a[2 * i].info, a[2 * i + 1].info));
  }
  void push(int v) {
    if (a[v].toadd == 0) return;
    a[2 * v].toadd += a[v].toadd;
    a[2 * v].info.value += a[v].toadd;
    a[2 * v + 1].toadd += a[v].toadd;
    a[2 * v + 1].info.value += a[v].toadd;
    a[v].toadd = 0;
  }
  void update(int v) {
    a[v] = NodeInfo(0, Info(a[2 * v].info, a[2 * v + 1].info));
  }
  void add(int v, int l, int r, int l0, int r0, int toadd) {
    if (l >= r0 || l0 >= r) return;
    if (l0 <= l && r <= r0) {
      a[v].toadd += toadd;
      a[v].info.value += toadd;
      return;
    }
    push(v);
    int m = (l + r) / 2;
    add(2 * v, l, m, l0, r0, toadd);
    add(2 * v + 1, m, r, l0, r0, toadd);
    update(v);
  }
  void add(int l, int r, int toadd) { add(1, 0, n, l, r, toadd); }
  int getVal() const {
    assert(a[1].info.value == 0);
    return wholeMask ^ a[1].info.mask;
  }
} tree;
int l;
struct Event {
  int type, x, l, r;
  Event() {}
  Event(int _type, int _x, int _l, int _r) : type(_type), x(_x), l(_l), r(_r) {}
  inline bool operator<(const Event &e) const {
    if (x != e.x) return x < e.x;
    return 0;
  }
};
const int maxn = (int)1e5 + 10;
Event evs[maxn];
int xs[maxn];
bool solve() {
  int n, m, k;
  if (scanf("%d%d%d", &n, &m, &k) < 2) return 0;
  int res = 0;
  l = 0;
  for (; (1 << l) <= k; ++l)
    ;
  int cnt = 0;
  for (int i = 0; i < m; ++i) {
    int a, b, c, d;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    --a, --b;
    evs[2 * i] = Event(0, a, b, d);
    evs[2 * i + 1] = Event(1, c, b, d);
    xs[cnt++] = b;
    xs[cnt++] = d;
  }
  sort(evs, evs + 2 * m);
  sort(xs, xs + cnt);
  cnt = unique(xs, xs + cnt) - xs;
  for (int i = 0; i < 2 * m; ++i) {
    evs[i].l = lower_bound(xs, xs + cnt, evs[i].l) - xs;
    evs[i].r = lower_bound(xs, xs + cnt, evs[i].r) - xs;
  }
  tree.build(cnt, xs, l);
  for (int i = 0; i < 2 * m; ++i) {
    Event &cur = evs[i];
    if (i > 0) {
      Info info(evs[i].x, evs[i - 1].x, l);
      int val = tree.getVal();
      for (int it = 0; it < l; ++it) {
        if (((info.mask >> it) & 1) && ((val >> it) & 1)) {
          res ^= (1 << it);
          res ^= (1 << it) / 2;
        }
      }
    }
    tree.add(cur.l, cur.r, !cur.type ? 1 : -1);
  }
  printf(res ? "Hamed\n" : "Malek\n");
  return 1;
}
int main() {
  srand(rdtsc());
  while (1) {
    if (!solve()) break;
  }
  return 0;
}

```