#include <bits/stdc++.h>
using namespace std;
int kValley = 0;
int kHills = 1;
int kIncreasing = 2;
int kDecreasing = 3;
struct Node {
  int maximum_answer[2] = {0, 0};
  int all_cover[4] = {0, 0, 0, 0};
  int prefix[4] = {0, 0, 0, 0};
  int suffix[4] = {0, 0, 0, 0};
  bool flipped = false;
};
void Print(const Node &a) {
  printf("***********************Begin**************************\n");
  printf("maximum answer is kValley %d  kHills %d\n", a.maximum_answer[kValley],
         a.maximum_answer[kHills]);
  printf("all cover is kValley %d  kHills %d kIncreasing %d kDecreasing %d\n",
         a.all_cover[kValley], a.all_cover[kHills], a.all_cover[kIncreasing],
         a.all_cover[kDecreasing]);
  printf("prefix is kValley %d  kHills %d kIncreasing %d kDecreasing %d\n",
         a.prefix[kValley], a.prefix[kHills], a.prefix[kIncreasing],
         a.prefix[kDecreasing]);
  printf("suffix is kValley %d  kHills %d kIncreasing %d kDecreasing %d\n",
         a.suffix[kValley], a.suffix[kHills], a.suffix[kIncreasing],
         a.suffix[kDecreasing]);
  printf("***********************End**************************\n");
}
int INF = 2e7;
int n, q;
char st[500010];
Node node_info[500010 * 8], answer;
Node flip_if_possible(const Node &node) {
  Node result = node;
  if (result.flipped) {
    swap(result.maximum_answer[0], result.maximum_answer[1]);
    swap(result.all_cover[0], result.all_cover[1]);
    swap(result.all_cover[2], result.all_cover[3]);
    swap(result.prefix[0], result.prefix[1]);
    swap(result.prefix[2], result.prefix[3]);
    swap(result.suffix[0], result.suffix[1]);
    swap(result.suffix[2], result.suffix[3]);
    result.flipped = false;
  }
  return result;
}
void trim(Node &node) {
  for (int i = 0; i < 4; ++i) {
    node.all_cover[i] = max(node.all_cover[i], -INF);
    node.prefix[i] = max(node.prefix[i], -INF);
    node.suffix[i] = max(node.suffix[i], -INF);
    if (i < 2) {
      node.maximum_answer[i] = max(node.maximum_answer[i], -INF);
    }
  }
}
Node Maintain(const Node &left_node_orig, const Node &right_node_orig) {
  Node left_node = left_node_orig, right_node = right_node_orig;
  left_node = flip_if_possible(left_node);
  right_node = flip_if_possible(right_node);
  Node result;
  result.flipped = false;
  result.maximum_answer[kValley] = max(left_node.maximum_answer[kValley],
                                       right_node.maximum_answer[kValley]);
  result.maximum_answer[kHills] =
      max(left_node.maximum_answer[kHills], right_node.maximum_answer[kHills]);
  result.maximum_answer[kValley] =
      max(result.maximum_answer[kValley],
          left_node.suffix[kValley] + right_node.prefix[kIncreasing]);
  result.maximum_answer[kValley] =
      max(result.maximum_answer[kValley],
          left_node.suffix[kDecreasing] + right_node.prefix[kValley]);
  result.maximum_answer[kValley] =
      max(result.maximum_answer[kValley],
          left_node.suffix[kDecreasing] + right_node.prefix[kIncreasing]);
  result.maximum_answer[kHills] =
      max(result.maximum_answer[kHills],
          left_node.suffix[kHills] + right_node.prefix[kDecreasing]);
  result.maximum_answer[kHills] =
      max(result.maximum_answer[kHills],
          left_node.suffix[kIncreasing] + right_node.prefix[kHills]);
  result.maximum_answer[kHills] =
      max(result.maximum_answer[kHills],
          left_node.suffix[kIncreasing] + right_node.prefix[kDecreasing]);
  result.all_cover[kIncreasing] =
      left_node.all_cover[kIncreasing] + right_node.all_cover[kIncreasing];
  result.all_cover[kDecreasing] =
      left_node.all_cover[kDecreasing] + right_node.all_cover[kDecreasing];
  result.all_cover[kValley] =
      max(left_node.all_cover[kValley] + right_node.all_cover[kIncreasing],
          left_node.all_cover[kDecreasing] + right_node.all_cover[kValley]);
  result.all_cover[kValley] =
      max(result.all_cover[kValley],
          left_node.all_cover[kDecreasing] + right_node.all_cover[kIncreasing]);
  result.all_cover[kHills] =
      max(left_node.all_cover[kHills] + right_node.all_cover[kDecreasing],
          left_node.all_cover[kIncreasing] + right_node.all_cover[kHills]);
  result.all_cover[kHills] =
      max(result.all_cover[kHills],
          left_node.all_cover[kIncreasing] + right_node.all_cover[kDecreasing]);
  result.prefix[kValley] =
      max(left_node.prefix[kValley],
          left_node.all_cover[kDecreasing] + right_node.prefix[kValley]);
  result.prefix[kValley] =
      max(result.prefix[kValley],
          left_node.all_cover[kValley] + right_node.prefix[kIncreasing]);
  result.prefix[kValley] =
      max(result.prefix[kValley],
          left_node.all_cover[kDecreasing] + right_node.prefix[kIncreasing]);
  result.prefix[kHills] =
      max(left_node.prefix[kHills],
          left_node.all_cover[kIncreasing] + right_node.prefix[kHills]);
  result.prefix[kHills] =
      max(result.prefix[kHills],
          left_node.all_cover[kHills] + right_node.prefix[kDecreasing]);
  result.prefix[kHills] =
      max(result.prefix[kHills],
          left_node.all_cover[kIncreasing] + right_node.prefix[kDecreasing]);
  result.prefix[kIncreasing] =
      max(left_node.prefix[kIncreasing],
          left_node.all_cover[kIncreasing] + right_node.prefix[kIncreasing]);
  result.prefix[kDecreasing] =
      max(left_node.prefix[kDecreasing],
          left_node.all_cover[kDecreasing] + right_node.prefix[kDecreasing]);
  result.suffix[kValley] =
      max(right_node.suffix[kValley],
          right_node.all_cover[kIncreasing] + left_node.suffix[kValley]);
  result.suffix[kValley] =
      max(result.suffix[kValley],
          right_node.all_cover[kValley] + left_node.suffix[kDecreasing]);
  result.suffix[kValley] =
      max(result.suffix[kValley],
          right_node.all_cover[kIncreasing] + left_node.suffix[kDecreasing]);
  result.suffix[kHills] =
      max(right_node.suffix[kHills],
          right_node.all_cover[kDecreasing] + left_node.suffix[kHills]);
  result.suffix[kHills] =
      max(result.suffix[kHills],
          right_node.all_cover[kHills] + left_node.suffix[kIncreasing]);
  result.suffix[kHills] =
      max(result.suffix[kHills],
          right_node.all_cover[kDecreasing] + left_node.suffix[kIncreasing]);
  result.suffix[kIncreasing] =
      max(right_node.suffix[kIncreasing],
          right_node.all_cover[kIncreasing] + left_node.suffix[kIncreasing]);
  result.suffix[kDecreasing] =
      max(right_node.suffix[kDecreasing],
          right_node.all_cover[kDecreasing] + left_node.suffix[kDecreasing]);
  trim(result);
  return result;
}
void BuildSegmentationTree(int node_id, int left, int right) {
  if (left == right) {
    int v = st[left - 1] == '>';
    node_info[node_id].maximum_answer[0] =
        node_info[node_id].maximum_answer[1] = 1;
    node_info[node_id].all_cover[0] = node_info[node_id].all_cover[1] = 1;
    node_info[node_id].all_cover[v + 2] = 1;
    node_info[node_id].all_cover[(v ^ 1) + 2] = -INF;
    for (int i = 0; i < 4; ++i) {
      node_info[node_id].prefix[i] = node_info[node_id].suffix[i] = -INF;
    }
    node_info[node_id].prefix[v + 2] = 1;
    node_info[node_id].suffix[v + 2] = 1;
    node_info[node_id].prefix[0] = node_info[node_id].suffix[0] = 1;
    node_info[node_id].prefix[1] = node_info[node_id].suffix[1] = 1;
    node_info[node_id].flipped = false;
    return;
  }
  int mid = (left + right) >> 1;
  BuildSegmentationTree(node_id * 2, left, mid);
  BuildSegmentationTree(node_id * 2 + 1, mid + 1, right);
  node_info[node_id] =
      Maintain(node_info[node_id * 2], node_info[node_id * 2 + 1]);
}
void Modify(int node_id, int tree_left, int tree_right, int query_left,
            int query_right) {
  if (query_right < tree_left || query_left > tree_right) {
    return;
  }
  if (query_left <= tree_left && tree_right <= query_right) {
    node_info[node_id].flipped ^= 1;
    return;
  }
  if (node_info[node_id].flipped) {
    node_info[node_id * 2].flipped ^= 1;
    node_info[node_id * 2 + 1].flipped ^= 1;
    node_info[node_id] = flip_if_possible(node_info[node_id]);
  }
  int mid = (tree_left + tree_right) >> 1;
  Modify(node_id * 2, tree_left, mid, query_left, query_right);
  Modify(node_id * 2 + 1, mid + 1, tree_right, query_left, query_right);
  node_info[node_id] =
      Maintain(node_info[node_id * 2], node_info[node_id * 2 + 1]);
}
void Query(int node_id, int tree_left, int tree_right, int query_left,
           int query_right) {
  if (query_right < tree_left || query_left > tree_right) {
    return;
  }
  if (node_info[node_id].flipped) {
    node_info[node_id * 2].flipped ^= 1;
    node_info[node_id * 2 + 1].flipped ^= 1;
    node_info[node_id] = flip_if_possible(node_info[node_id]);
  }
  if (query_left <= tree_left && tree_right <= query_right) {
    answer = Maintain(answer, node_info[node_id]);
    return;
  }
  int mid = (tree_left + tree_right) >> 1;
  Query(node_id * 2, tree_left, mid, query_left, query_right);
  Query(node_id * 2 + 1, mid + 1, tree_right, query_left, query_right);
}
int main() {
  scanf("%d%d", &n, &q);
  scanf("%s", &st);
  BuildSegmentationTree(1, 1, n);
  for (int i = 0; i < q; ++i) {
    int l, r;
    scanf("%d%d", &l, &r);
    answer = Node();
    Modify(1, 1, n, l, r);
    Query(1, 1, n, l, r);
    printf("%d\n", answer.maximum_answer[kValley]);
  }
  return 0;
}
