#include <bits/stdc++.h>
#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("sse4.2")
using namespace std;
mt19937 gen(chrono::high_resolution_clock::now().time_since_epoch().count());
template <class T, class U>
inline bool chmax(T &x, U y) {
  return x < y ? x = y, 1 : 0;
}
template <class T, class U>
inline bool chmin(T &x, U y) {
  return x > y ? x = y, 1 : 0;
}
template <class T>
inline void sort(T &a) {
  sort((a).begin(), (a).end());
}
template <class T>
inline void rsort(T &a) {
  sort((a).rbegin(), (a).rend());
}
template <class T>
inline void reverse(T &a) {
  reverse((a).begin(), (a).end());
}
template <class T, class U>
inline istream &operator>>(istream &str, pair<T, U> &p) {
  return str >> p.first >> p.second;
}
template <class T>
inline istream &operator>>(istream &str, vector<T> &a) {
  for (auto &i : a) str >> i;
  return str;
}
template <class T>
inline T sorted(T a) {
  sort(a);
  return a;
}
void read() {}
void print() {}
void println() { cout << '\n'; }
template <class T, class... U>
void read(T &x, U &...u) {
  cin >> x;
  read(u...);
}
template <class T, class... U>
void print(const T &x, const U &...u) {
  cout << x;
  print(u...);
}
template <class T, class... U>
void println(const T &x, const U &...u) {
  cout << x;
  println(u...);
}
struct stats {
  int val[8] = {0, 0, 0, 0, 0, 0, 0, 0};
  int best = 0, revbest = 0;
  int len;
  void rev() {
    swap(val[0], val[1]);
    swap(val[2], val[3]);
    swap(val[4], val[5]);
    swap(val[6], val[7]);
    swap(best, revbest);
  }
  void updstats(string second) {
    int ptr = 0;
    while (ptr < len && second[ptr] == '<') ++ptr;
    val[0] = ptr;
    while (ptr < len && second[ptr] == '>') ++ptr;
    val[3] = ptr;
    ptr = 0;
    while (ptr < len && second[ptr] == '>') ++ptr;
    val[1] = ptr;
    while (ptr < len && second[ptr] == '<') ++ptr;
    val[2] = ptr;
    ptr = len - 1;
    while (ptr >= 0 && second[ptr] == '>') --ptr;
    val[4] = len - 1 - ptr;
    while (ptr >= 0 && second[ptr] == '<') --ptr;
    val[7] = len - 1 - ptr;
    ptr = len - 1;
    while (ptr >= 0 && second[ptr] == '<') --ptr;
    val[5] = len - 1 - ptr;
    while (ptr >= 0 && second[ptr] == '>') --ptr;
    val[6] = len - 1 - ptr;
    best = max(val[2], val[6]);
    revbest = max(val[3], val[7]);
  }
  int &operator[](int ind) { return val[ind]; }
  int operator[](int ind) const { return val[ind]; }
  friend stats merge(stats a, stats b) {
    stats ans;
    ans.best = max(a.best, b.best);
    ans.revbest = max(a.revbest, b.revbest);
    ans.len = a.len + b.len;
    ans[0] = a[0];
    ans[1] = a[1];
    ans[2] = a[2];
    ans[3] = a[3];
    ans[4] = b[4];
    ans[5] = b[5];
    ans[6] = b[6];
    ans[7] = b[7];
    if (a[0] == a.len) {
      chmax(ans[0], a[0] + b[0]);
      chmax(ans[3], a[0] + b[3]);
    }
    if (a[1] == a.len) {
      chmax(ans[1], a[1] + b[1]);
      chmax(ans[2], a[1] + b[2]);
    }
    if (a[2] == a.len) {
      chmax(ans[2], a[2] + b[0]);
    }
    if (a[3] == a.len) {
      chmax(ans[3], a[3] + b[1]);
    }
    if (b[4] == b.len) {
      chmax(ans[4], b[4] + a[4]);
      chmax(ans[7], b[4] + a[7]);
    }
    if (b[5] == b.len) {
      chmax(ans[5], b[5] + a[5]);
      chmax(ans[6], b[5] + a[6]);
    }
    if (b[6] == b.len) {
      chmax(ans[6], b[6] + a[4]);
    }
    if (b[7] == b.len) {
      chmax(ans[7], b[7] + a[5]);
    }
    chmax(ans.best, ans[2]);
    chmax(ans.best, ans[6]);
    chmax(ans.revbest, ans[3]);
    chmax(ans.revbest, ans[7]);
    chmax(ans.best, a[6] + b[0]);
    chmax(ans.best, a[4] + b[2]);
    chmax(ans.revbest, a[7] + b[1]);
    chmax(ans.revbest, a[5] + b[3]);
    return ans;
  }
};
struct node {
  stats second;
  bool rev = false;
  node() {}
  node(string t) {
    second.len = signed((t).size());
    second.updstats(t);
  }
  void upd(bool flag) {
    if (flag) {
      rev ^= true;
      second.rev();
    }
  }
  void upd(const node &t) { upd(t.rev); }
  bool updated() const { return rev != 0; }
  void unupdate() { rev = 0; }
};
node merge(const node &a, const node &b) {
  node ans;
  ans.second = merge(a.second, b.second);
  return ans;
}
template <class node, node (*merge)(const node &, const node &) = merge>
struct Tree {
  int n = 1;
  vector<node> t;
  node &operator[](int ind) { return t[ind + n]; }
  const node &operator[](int ind) const { return t[ind + n]; }
  void submerge(int v) {
    if (v >= n) return;
    t[v] = merge(t[v + v], t[v + v + 1]);
  }
  void resize(int sz) {
    while (n < sz) n <<= 1;
    t.resize(2 * n + 1);
  }
  void blank() {
    for (int i = 0; i < 2 * n; ++i) t[i] = node();
  }
  void build() {
    for (int i = n - 1; i > 0; --i) submerge(i);
  }
  template <class T>
  void assign(const vector<T> &a) {
    resize(signed((a).size()));
    for (int i = 0; i < signed((a).size()); ++i) t[i + n] = a[i];
    for (int i = signed((a).size()); i < n; ++i) t[i + n] = node();
    build();
  }
  Tree() {}
  Tree(int sz) {
    resize(sz);
    blank();
  }
  template <class T>
  Tree(const vector<T> &a) {
    assign(a);
  }
  template <class T>
  void updup(int i, const T &val) {
    i += n;
    t[i].upd(val);
    for (i >>= 1; i > 0; i >>= 1) submerge(i);
  }
  node getup(int l, int r) {
    l += n;
    r += n;
    int cr = r;
    node left, right;
    bool lf = true, rf = true;
    for (; l < r; l >>= 1, r >>= 1) {
      if (l & 1) left = lf ? lf = false, t[l++] : merge(left, t[l++]);
      if (r & 1) right = rf ? rf = false, t[--r] : merge(t[--r], right);
    }
    if (lf) return right;
    if (rf) return left;
    return merge(left, right);
  }
  void push(int v) {
    if (t[v].updated()) {
      t[v + v].upd(t[v]);
      t[v + v + 1].upd(t[v]);
      t[v].unupdate();
    }
  }
  template <class T>
  void upd(int l, int r, const T &x, int v, int vl, int vr) {
    if (vl >= r || vr <= l) return;
    if (vl >= l && vr <= r) return t[v].upd(x);
    push(v);
    int vm = vl + vr >> 1;
    upd(l, r, x, v + v, vl, vm);
    upd(l, r, x, v + v + 1, vm, vr);
    submerge(v);
  }
  template <class T>
  void upd(int l, int r, const T &x) {
    upd(l, r, x, 1, 0, n);
  }
  node get(int l, int r, int v, int vl, int vr) {
    if (vl >= r || vr <= l) return node();
    if (vl >= l && vr <= r) return t[v];
    push(v);
    int vm = vl + vr >> 1;
    if (r <= vm) return get(l, r, v + v, vl, vm);
    if (l >= vm) return get(l, r, v + v + 1, vm, vr);
    return merge(get(l, r, v + v, vl, vm), get(l, r, v + v + 1, vm, vr));
  }
  node get(int l, int r) { return get(l, r, 1, 0, n); }
};
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cout << fixed << setprecision(12);
  int n, q;
  read(n, q);
  string second;
  read(second);
  Tree<node> t(n);
  for (int i = 0; i < n; ++i) t[i] = string(1, second[i]);
  t.build();
  while (q--) {
    int l, r;
    read(l, r);
    --l;
    t.upd(l, r, 1);
    println(t.get(l, r).second.best);
  }
  return 0;
}
