#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool checkMax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T, typename... Args>
inline void checkMax(T &a, const Args... arg) {
  checkMax(a, max(arg...));
}
template <class T>
inline bool checkMin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T, typename... Args>
inline void checkMin(T &a, const Args... arg) {
  checkMin(a, min(arg...));
}
const int INF = 0x3f3f3f3f;
const long long llINF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 2e5 + 5;
int n, m, K, cnt, tot;
int a[MAXN];
long long num[MAXN];
struct Rect {
  int x100, y100, x2, y2;
} rec[MAXN];
struct Line {
  int x, y100, y2, op;
} line[MAXN];
struct SegmentTree {
  static const int MAXM = MAXN << 2;
  struct Tree {
    int l, r;
    int cov, sum;
  } tree[MAXM];
  void update(int k) {
    if (tree[k].cov > 0)
      tree[k].sum = a[tree[k].r] - a[tree[k].l - 1];
    else
      tree[k].sum = tree[k << 1].sum + tree[k << 1 | 1].sum;
  }
  void build(int k, int l, int r) {
    tree[k].l = l;
    tree[k].r = r;
    tree[k].cov = tree[k].sum = 0;
    if (l == r) return;
    int mid = (l + r) >> 1;
    build(k << 1, l, mid);
    build(k << 1 | 1, mid + 1, r);
  }
  void modify(int k, int l, int r, int v) {
    if (tree[k].l >= l && tree[k].r <= r) {
      tree[k].cov += v;
      update(k);
      return;
    }
    int mid = (tree[k].l + tree[k].r) >> 1;
    if (l <= mid) modify(k << 1, l, r, v);
    if (r > mid) modify(k << 1 | 1, l, r, v);
    update(k);
  }
  int query() { return tree[1].sum; }
} T;
long long Solve(int t) {
  tot = cnt = 0;
  for (int i = 1; i <= m; i++) {
    int x100 = (rec[i].x100 - 1) / t + 1, x2 = rec[i].x2 / t;
    int y100 = (rec[i].y100 - 1) / t + 1, y2 = rec[i].y2 / t;
    if (x100 > x2 || y100 > y2) continue;
    a[++cnt] = y100 - 1, a[++cnt] = y2;
    line[++tot] = {x100 - 1, y100, y2, 1};
    line[++tot] = {x2, y100, y2, -1};
  }
  if (!tot) return 0;
  sort(a + 1, a + 1 + cnt);
  cnt = unique(a + 1, a + 1 + cnt) - a - 1;
  T.build(1, 1, cnt);
  sort(line + 1, line + 1 + tot,
       [](const Line &x, const Line &y) { return x.x < y.x; });
  long long ans = 0;
  for (int i = 1; i <= tot; i++) {
    ans += (long long)(line[i].x - line[i - 1].x) * T.query();
    int y100 = lower_bound(a + 1, a + 1 + cnt, line[i].y100) - a;
    int y2 = lower_bound(a + 1, a + 1 + cnt, line[i].y2) - a;
    T.modify(1, y100, y2, line[i].op);
  }
  return ans;
}
int main() {
  scanf("%d%d%d", &n, &m, &K);
  for (int i = 1; i <= m; i++) {
    int x100, y100, x2, y2;
    scanf("%d%d%d%d", &x100, &y100, &x2, &y2);
    rec[i] = {x100, y100, x2, y2};
  }
  int w = 0;
  while ((1 << (w + 1)) <= K) w += 1;
  for (int i = 0; i <= w; i++) {
    num[i] = Solve(1 << i);
    if (i && ((num[i] - num[i - 1]) & 1)) {
      printf("Hamed");
      return 0;
    }
  }
  if (num[w] & 1)
    printf("Hamed\n");
  else
    printf("Malek\n");
  return 0;
}
