#include <bits/stdc++.h>
using namespace std;
long long MOD(long long x, long long m) {
  long long r = x % m;
  if (r < 0) {
    r += m;
  }
  return r;
}
ostream& operator<<(ostream& str, const pair<long long, long long>& p) {
  str << p.first << " " << p.second;
  return str;
}
template <typename T>
void join(T& arr, string sep) {
  bool first = true;
  for (auto t : arr) {
    if (first) {
      first = false;
      cout << t;
    } else {
      cout << sep << t;
    }
  }
  cout << "\n";
}
struct SegmentTree {
  struct TreeNode {
    long long __prefix0 = 0;
    long long __prefix1 = 0;
    long long __prefix01 = 0;
    long long __prefix10 = 0;
    long long __suffix0 = 0;
    long long __suffix1 = 0;
    long long __suffix10 = 0;
    long long __suffix01 = 0;
    long long __max01 = 0;
    long long __max10 = 0;
    long long __max1 = 0;
    long long __max0 = 0;
    long long __size = 0;
    long long __pendingDelta = 0;
    pair<long long, long long> __pendingOverwrite = {0, 0};
    TreeNode() {}
    TreeNode(long long x, long long i) { init(x, i); }
    void init(long long x, long long i) {
      __prefix0 = x == 0 ? 1 : 0;
      __prefix1 = x == 1 ? 1 : 0;
      __suffix1 = x == 1 ? 1 : 0;
      __suffix0 = x == 0 ? 1 : 0;
      __suffix01 = 0;
      __suffix10 = 0;
      __prefix01 = 0;
      __prefix10 = 0;
      __max01 = 0;
      __max10 = 0;
      __max1 = x == 1 ? 1 : 0;
      __max0 = x == 0 ? 1 : 0;
      __size = 1;
    }
    vector<long long> result() { return {__max01, __max0, __max1}; }
    static TreeNode join(TreeNode& n1, TreeNode& n2) {
      assert(!n1.__pendingDelta && !n1.__pendingOverwrite.first);
      assert(!n2.__pendingDelta && !n2.__pendingOverwrite.first);
      TreeNode res;
      if (n1.__prefix0 == n1.__size) {
        res.__prefix0 = n1.__prefix0 + n2.__prefix0;
      } else {
        res.__prefix0 = n1.__prefix0;
      }
      if (n1.__prefix1 == n1.__size) {
        res.__prefix1 = n1.__prefix1 + n2.__prefix1;
      } else {
        res.__prefix1 = n1.__prefix1;
      }
      if (n2.__suffix0 == n2.__size) {
        res.__suffix0 = n2.__suffix0 + n1.__suffix0;
      } else {
        res.__suffix0 = n2.__suffix0;
      }
      if (n2.__suffix1 == n2.__size) {
        res.__suffix1 = n2.__suffix1 + n1.__suffix1;
      } else {
        res.__suffix1 = n2.__suffix1;
      }
      res.__prefix01 = n1.__prefix01;
      if (n1.__prefix01 == n1.__size) {
        res.__prefix01 += n2.__prefix1;
      }
      if (n1.__prefix0 == n1.__size &&
          (n2.__prefix1 > 0 || n2.__prefix01 > 0)) {
        res.__prefix01 = n1.__prefix0 + max(n2.__prefix1, n2.__prefix01);
      }
      res.__prefix10 = n1.__prefix10;
      if (n1.__prefix10 == n1.__size) {
        res.__prefix10 += n2.__prefix0;
      }
      if (n1.__prefix1 == n1.__size &&
          (n2.__prefix0 > 0 || n2.__prefix10 > 0)) {
        res.__prefix10 = n1.__prefix1 + max(n2.__prefix0, n2.__prefix10);
      }
      res.__suffix01 = n2.__suffix01;
      if (n2.__suffix01 == n2.__size) {
        res.__suffix01 += n1.__suffix0;
      }
      if (n2.__suffix1 == n2.__size &&
          (n1.__suffix0 > 0 || n1.__suffix01 > 0)) {
        res.__suffix01 = n2.__suffix1 + max(n1.__suffix0, n1.__suffix01);
      }
      res.__suffix10 = n2.__suffix10;
      if (n2.__suffix10 == n2.__size) {
        res.__suffix10 += n1.__suffix1;
      }
      if (n2.__suffix0 == n2.__size &&
          (n1.__suffix1 > 0 || n1.__suffix10 > 0)) {
        res.__suffix10 = n2.__suffix0 + max(n1.__suffix1, n1.__suffix10);
      }
      res.__max01 = max(n1.__max01, n2.__max01);
      if (n1.__suffix0 > 0 && n2.__prefix1 > 0)
        res.__max01 = max(res.__max01, n1.__suffix0 + n2.__prefix1);
      if (n2.__prefix01 > 0)
        res.__max01 = max(res.__max01, n1.__suffix0 + n2.__prefix01);
      if (n1.__suffix01 > 0)
        res.__max01 = max(res.__max01, n1.__suffix01 + n2.__prefix1);
      res.__max10 = max(n1.__max10, n2.__max10);
      if (n1.__suffix1 > 0 && n2.__prefix0 > 0)
        res.__max10 = max(res.__max10, n1.__suffix1 + n2.__prefix0);
      if (n2.__prefix10 > 0)
        res.__max10 = max(res.__max10, n1.__suffix1 + n2.__prefix10);
      if (n1.__suffix10 > 0)
        res.__max10 = max(res.__max10, n1.__suffix10 + n2.__prefix0);
      res.__max1 = max(n1.__max1, n2.__max1);
      res.__max1 = max(res.__max1, n1.__suffix1 + n2.__prefix1);
      res.__max0 = max(n1.__max0, n2.__max0);
      res.__max0 = max(res.__max0, n1.__suffix0 + n2.__prefix0);
      res.__size = n1.__size + n2.__size;
      return res;
    }
  };
  vector<TreeNode> __tree;
  long long __n;
  SegmentTree(long long n) : __n(n) {
    vector<long long> arr(n);
    __tree = vector<TreeNode>(arr.size() * 4);
    init(0, arr.size() - 1, 0, arr);
  }
  SegmentTree(vector<long long> arr) {
    __tree = vector<TreeNode>(arr.size() * 4);
    __n = arr.size();
    init(0, arr.size() - 1, 0, arr);
  }
  vector<long long> query(long long l, long long r) {
    assert(l <= r && l >= 0 && r < __n);
    return queryHelper(0, __n - 1, 0, l, r).result();
  }
  TreeNode queryHelper(long long s, long long e, long long i, long long l,
                       long long r) {
    applyPendingChanges(s, e, i);
    if (l == s && r == e) {
      return __tree[i];
    }
    long long m = SegmentTree::middleIdx(s, e);
    if (r <= m) {
      return queryHelper(s, m, SegmentTree::leftIdx(i), l, r);
    }
    if (l > m) {
      return queryHelper(m + 1, e, SegmentTree::rightIdx(i), l, r);
    }
    TreeNode left = queryHelper(s, m, SegmentTree::leftIdx(i), l, m);
    TreeNode right = queryHelper(m + 1, e, SegmentTree::rightIdx(i), m + 1, r);
    return TreeNode::join(left, right);
  }
  void updataRangeHelper(long long s, long long e, long long i, long long l,
                         long long r, long long v, bool isDelta) {
    applyPendingChanges(s, e, i);
    if (l == s && r == e) {
      if (isDelta) {
        __tree[i].__pendingDelta = v;
      } else {
        __tree[i].__pendingOverwrite = {1, v};
      }
      applyPendingChanges(s, e, i);
      return;
    }
    long long m = SegmentTree::middleIdx(s, e);
    long long lidx = SegmentTree::leftIdx(i);
    long long ridx = SegmentTree::rightIdx(i);
    if (r <= m) {
      updataRangeHelper(s, m, lidx, l, r, v, isDelta);
      applyPendingChanges(m + 1, e, ridx);
    } else if (l > m) {
      updataRangeHelper(m + 1, e, ridx, l, r, v, isDelta);
      applyPendingChanges(s, m, lidx);
    } else {
      updataRangeHelper(s, m, lidx, l, m, v, isDelta);
      updataRangeHelper(m + 1, e, ridx, m + 1, r, v, isDelta);
    }
    __tree[i] = TreeNode::join(__tree[lidx], __tree[ridx]);
  }
  void updateRange(long long l, long long r, long long v) {
    assert(l >= 0 && r < __n && l <= r);
    updataRangeHelper(0, __n - 1, 0, l, r, v, false);
  }
  void addToRange(long long l, long long r, long long d) {
    assert(l >= 0 && r < __n && l <= r);
    updataRangeHelper(0, __n - 1, 0, l, r, d, true);
  }
  void add(long long i, long long d) { addToRange(i, i, d); }
  void update(long long i, long long v) { updateRange(i, i, v); }
  void init(long long s, long long e, long long i, vector<long long>& arr) {
    assert(s <= e && i < __tree.size());
    if (s == e) {
      __tree[i].init(arr[s], s);
      return;
    }
    long long m = SegmentTree::middleIdx(s, e);
    long long l = SegmentTree::leftIdx(i);
    long long r = SegmentTree::rightIdx(i);
    init(s, m, l, arr);
    init(m + 1, e, r, arr);
    auto& left = __tree[l];
    auto& right = __tree[r];
    __tree[i] = TreeNode::join(left, right);
  }
  void applyPendingChanges(long long s, long long e, long long j) {
    TreeNode& treeNode = __tree[j];
    pair<long long, long long> pendingOverwrite = treeNode.__pendingOverwrite;
    long long pendingDelta = treeNode.__pendingDelta;
    if (pendingOverwrite.first) {
      assert(false);
    }
    if (pendingDelta) {
      if (pendingDelta % 2 == 1) {
        swap(treeNode.__prefix0, treeNode.__prefix1);
        swap(treeNode.__suffix0, treeNode.__suffix1);
        swap(treeNode.__prefix01, treeNode.__prefix10);
        swap(treeNode.__suffix01, treeNode.__suffix10);
        swap(treeNode.__max01, treeNode.__max10);
        swap(treeNode.__max1, treeNode.__max0);
      }
      treeNode.__pendingDelta = 0;
    }
    if (s == e || !pendingOverwrite.first && !pendingDelta) return;
    long long l = SegmentTree::leftIdx(j);
    long long r = SegmentTree::rightIdx(j);
    auto& left = __tree[l];
    auto& right = __tree[r];
    if (pendingOverwrite.first) {
      left.__pendingDelta = 0;
      left.__pendingOverwrite = pendingOverwrite;
      right.__pendingDelta = 0;
      right.__pendingOverwrite = pendingOverwrite;
    }
    if (pendingDelta) {
      left.__pendingDelta += pendingDelta;
      right.__pendingDelta += pendingDelta;
    }
  }
  static long long leftIdx(long long i) { return i * 2 + 1; }
  static long long rightIdx(long long i) { return i * 2 + 2; }
  static long long middleIdx(long long s, long long e) { return (s + e) / 2; }
};
void solve() {
  long long n, q;
  cin >> n >> q;
  string s;
  cin >> s;
  vector<long long> pro_s(n);
  for (long long i = 0; i < (long long)(n); ++i) {
    if (s[i] == '<') {
      pro_s[i] = 1;
    } else {
      pro_s[i] = 0;
    }
  }
  SegmentTree st(pro_s);
  for (long long i = 0; i < (long long)(q); ++i) {
    long long l, r;
    cin >> l >> r;
    l--;
    r--;
    st.addToRange(l, r, 1);
    vector<long long> res = st.query(l, r);
    cout << max({res[0], res[1], res[2]}) << "\n";
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int tt = 1;
  for (int t = 1; t <= tt; t++) {
    solve();
  }
  return 0;
}
