#include <bits/stdc++.h>
std::istream& in = std::cin;
std::ostream& out = std::cout;
enum { LT, LE, EQ, GE, GT };
const int MaxN = 80;
const int MaxM = 105;
std::pair<int, int> criteria[MaxN][MaxM];
long long dp[MaxN][MaxN];
int criteria_n[MaxN], n;
int get_id(const char* op) {
  if (op[0] == '<')
    return op[1] == 0 ? LT : LE;
  else if (op[0] == '=')
    return EQ;
  else
    return op[1] == 0 ? GT : GE;
}
bool valid0(int l, int r, int first_pos, int second_pos) {
  bool ok = true;
  for (int i = 0; ok && i < criteria_n[first_pos]; i++) {
    const auto& ref = criteria[first_pos][i];
    if (ref.second == EQ)
      ok &= ref.first == first_pos || ref.first == second_pos;
    else if (ref.second == LE)
      ok &= ref.first >= l && ref.first <= r;
    else if (ref.second == GE)
      ok &= ref.first <= l || ref.first >= r || ref.first == first_pos ||
            ref.first == second_pos;
    else if (ref.second == LT)
      ok &= ref.first >= l && ref.first <= r && ref.first != first_pos &&
            ref.first != second_pos;
    else
      ok &= ref.first < l || ref.first > r;
  }
  return ok;
}
bool valid(int l, int r, int first_pos, int second_pos) {
  return valid0(l, r, first_pos, second_pos) &&
         valid0(l, r, second_pos, first_pos);
}
long long dfs(int l, int r) {
  long long& res = dp[l][r];
  if (res != -1) return res;
  res = 0;
  if (l + 1 == r) return res = valid(l, r, l, r);
  if (valid(l, r, l, l + 1)) res += dfs(l + 2, r);
  if (valid(l, r, l, r)) res += dfs(l + 1, r - 1);
  if (valid(l, r, r - 1, r)) res += dfs(l, r - 2);
  return res;
}
int main() {
  int m;
  char op[5];
  int id1, id2;
  std::ios_base::sync_with_stdio(false);
  while (in >> n >> m) {
    for (int i = 1; i <= n * 2; i++) criteria_n[i] = 0;
    for (int i = 0; i < m; i++) {
      in >> id1 >> op >> id2;
      criteria[id1][criteria_n[id1]++] = {id2, get_id(op)};
      criteria[id2][criteria_n[id2]++] = {id1, 4 - get_id(op)};
    }
    memset(dp, -1, sizeof(dp));
    out << dfs(1, 2 * n) << std::endl;
  }
  return 0;
}
