/* ***********************************************
Author :111qqz
Created Time :2016年03月07日 星期一 17时06分53秒
File Name :code/cf/#345/C.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define fst first
#define sec second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(a,x) memset(a,x,sizeof(a))
typedef long long LL;
#define pi pair < int ,int >
#define MP make_pair

using namespace std;
const double eps = 1E-8;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
const int inf = 0x3f3f3f3f;
const int N=2E5+7;
LL a,b,c;
int n;
struct node
{
    LL x,y;

    bool operator < (node b)const
    {
	if (x==b.x) return y<b.y;
	return x<b.x;
    }
}p[N];
LL cal( LL x)
{
    LL res ;
    res = x*(x+1)/2;
}
bool cmp(node a,node b)
{
    return a.y<b.y;
}
int main()
{
	#ifndef  ONLINE_JUDGE
	freopen("code/in.txt","r",stdin);
  #endif
	ios::sync_with_stdio(false);
	cin>>n;
	if (n==1)
	{
	    puts("0");
	    return  0;
	}
	for ( int i  = 0 ; i < n ; i++) cin>>p[i].x>>p[i].y;
	sort(p,p+n);

	a = 0 ;
	b = 0 ;
	c = 0 ;
	LL cnta=0,cntb=0,cntc=0;
	p[n].x=inf;
	p[n].y=inf;
	for ( int i = 0 ; i < n ; i++)
	{
	    if (p[i].x==p[i+1].x)
	    {
		cnta++;
		if (p[i].y==p[i+1].y) cntc++;
		else
		{
		    c +=cal(cntc);
		    cntc = 0 ;
		}
	    }
	    else
	    {
		a +=cal(cnta);
		cnta = 0 ;
	    }
	}

	sort(p,p+n,cmp);

	for ( int i = 0 ; i< n ; i++)
	{
	    if (p[i].y==p[i+1].y)
	    {
		cntb++;
	    }
	    else
	    {
		b +=cal(cntb);
		cntb = 0 ;
	    }
	}

	LL ans =0LL;
//	cout<<"a:"<<a<<" b:"<<b<<" c:"<<c<<endl;
	ans = ans +a + b - c;
	cout<<ans<<endl;

  #ifndef ONLINE_JUDGE
  fclose(stdin);
  #endif
    return 0;
}


/* ***********************************************
Author :111qqz
Created Time :2016年03月07日 星期一 17时06分53秒
File Name :code/cf/#345/C.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define fst first
#define sec second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(a,x) memset(a,x,sizeof(a))
typedef long long LL;
#define pi pair < int ,int >
#define MP make_pair

using namespace std;
const double eps = 1E-8;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
const int inf = 0x3f3f3f3f;
const int N=2E5+7;
LL a,b,c;
int n;
struct node
{
    LL x,y;

    bool operator < (node b)const
    {
	if (x==b.x) return y<b.y;
	return x<b.x;
    }
}p[N];
LL cal( LL x)
{
    LL res ;
    res = x*(x+1)/2;
}
bool cmp(node a,node b)
{
    return a.y<b.y;
}
int main()
{
	#ifndef  ONLINE_JUDGE
	freopen("code/in.txt","r",stdin);
 #endif
//	ios::sync_with_stdio(false);
	cin>>n;
//	if (n==1)
//	{
//	    puts("0");
//	    return  0;
//	}
	for ( int i  = 0 ; i < n ; i++) cin>>p[i].x>>p[i].y;
	sort(p,p+n);

	a = 0 ;
	b = 0 ;
	c = 0 ;
	LL cnta=0,cntb=0,cntc=0;
//	p[n].x=inf;
//	p[n].y=inf;
	for ( int i = 0 ; i < n ; i++)
	{
	    if (i!=n-1&&p[i].x==p[i+1].x)
	    {
		cnta++;
	    }
	    else
	    {
		a +=cal(cnta);
		cnta = 0 ;
	    }
	}

	for ( int i = 0 ; i < n ; i++)
	{
	    if (i!=n-1&&p[i].x==p[i+1].x&&p[i].y==p[i+1].y)
	    {
		cntc++;
	    }
	    else
	    {
		c+=cal(cntc);
		cntc = 0;
	    }
	}

	sort(p,p+n,cmp);

	for ( int i = 0 ; i< n ; i++)
	{

//	    cout<<"x:"<<p[i].x<<" y:"<<p[i].y<<endl;
	    if (i!=n-1&&p[i].y==p[i+1].y)
	    {
		cntb++;
	    }
	    else
	    {
		b +=cal(cntb);
		cntb = 0 ;
	    }
	}

	LL ans =0LL;
//	cout<<"a:"<<a<<" b:"<<b<<" c:"<<c<<endl;
	ans = ans +a + b - c;
	cout<<ans<<endl;

//  #ifndef ONLINE_JUDGE
 // fclose(stdin);
//  #endif
    return 0;
}


/* ***********************************************
Author :111qqz
Created Time :2016年03月07日 星期一 17时06分53秒
File Name :code/cf/#345/C.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define fst first
#define sec second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(a,x) memset(a,x,sizeof(a))
typedef long long LL;
#define pi pair < int ,int >
#define MP make_pair

using namespace std;
const double eps = 1E-8;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
const int inf = 0x3f3f3f3f;
const int N=2E5+7;
LL a,b,c;
int n;
struct node
{
    LL x,y;

    bool operator < (node b)const
    {
	if (x==b.x) return y<b.y;
	return x<b.x;
    }
}p[N];
LL cal( LL x)
{
    LL res ;
    res = x*(x+1)/2;
}
bool cmp(node a,node b)
{
    return a.y<b.y;
}
int main()
{
	#ifndef  ONLINE_JUDGE
	freopen("code/in.txt","r",stdin);
  #endif
	ios::sync_with_stdio(false);
	cin>>n;
	if (n==1)
	{
	    puts("0");
	    return  0;
	}
	for ( int i  = 0 ; i < n ; i++) cin>>p[i].x>>p[i].y;
	sort(p,p+n);

	a = 0 ;
	b = 0 ;
	c = 0 ;
	for ( int i = 0 ; i < n-1 ; i++)
	{
	    if (p[i].x==p[i+1].x)
	    {
		a++;
		if (p[i].y==p[i+1].y) c++;
	    }
	}

	sort(p,p+n,cmp);

	for ( int i = 0 ; i< n-1 ; i++)
	{
	    if (p[i].y==p[i+1].y)
		b++;
	}

	LL ans =0LL;
	ans = ans +cal(a)+cal(b)-cal(c);
	cout<<ans<<endl;

  #ifndef ONLINE_JUDGE
  fclose(stdin);
  #endif
    return 0;
}


/* ***********************************************
Author :111qqz
Created Time :2016年03月07日 星期一 17时06分53秒
File Name :code/cf/#345/C.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define fst first
#define sec second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(a,x) memset(a,x,sizeof(a))
typedef long long LL;
#define pi pair < int ,int >
#define MP make_pair

using namespace std;
const double eps = 1E-8;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
const int inf = 0x3f3f3f3f;
const int N=2E5+7;
LL a,b,c;
int n;
struct node
{
    LL x,y;

    bool operator < (node b)const
    {
	if (x==b.x) return y<b.y;
	return x<b.x;
    }
}p[N];
LL cal( LL x)
{
    LL res ;
    res = x*(x+1)/2;
}
bool cmp(node a,node b)
{
    return a.y<b.y;
}
int main()
{
//	#ifndef  ONLINE_JUDGE
//	freopen("code/in.txt","r",stdin);
//  #endif
//	ios::sync_with_stdio(false);
	cin>>n;
	if (n==1)
	{
	    puts("0");
	    return  0;
	}
	for ( int i  = 0 ; i < n ; i++) cin>>p[i].x>>p[i].y;
	sort(p,p+n);

	a = 0 ;
	b = 0 ;
	c = 0 ;
	LL cnta=0,cntb=0,cntc=0;
//	p[n].x=inf;
//	p[n].y=inf;
	for ( int i = 0 ; i < n ; i++)
	{
	    if (i!=n-1&&p[i].x==p[i+1].x)
	    {
		cnta++;
	    }
	    else
	    {
		a +=cal(cnta);
		cnta = 0 ;
	    }
	}

	for ( int i = 0 ; i < n ; i++)
	{
	    if (i!=n-1&&p[i].x==p[i+1].x&&p[i].y==p[i+1].y)
	    {
		cntc++;
	    }
	    else
	    {
		c+=cal(cntc);
		cntc = 0;
	    }
	}

	sort(p,p+n,cmp);

	for ( int i = 0 ; i< n ; i++)
	{

//	    cout<<"x:"<<p[i].x<<" y:"<<p[i].y<<endl;
	    if (i!=n-1&&p[i].y==p[i+1].y)
	    {
		cntb++;
	    }
	    else
	    {
		b +=cal(cntb);
		cntb = 0 ;
	    }
	}

	LL ans =0LL;
//	cout<<"a:"<<a<<" b:"<<b<<" c:"<<c<<endl;
	ans = ans +a + b - c;
	cout<<ans<<endl;

//  #ifndef ONLINE_JUDGE
 // fclose(stdin);
//  #endif
    return 0;
}


/* ***********************************************
Author :111qqz
Created Time :2016年03月07日 星期一 17时06分53秒
File Name :code/cf/#345/C.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define fst first
#define sec second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(a,x) memset(a,x,sizeof(a))
typedef long long LL;
#define pi pair < int ,int >
#define MP make_pair

using namespace std;
const double eps = 1E-8;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
const int inf = 0x3f3f3f3f;
const int N=2E5+7;
LL a,b,c;
int n;
struct node
{
    LL x,y;

    bool operator < (node b)const
    {
	if (x==b.x) return y<b.y;
	return x<b.x;
    }
}p[N];
LL cal( LL x)
{
    LL res ;
    res = x*(x+1)/2;
}
bool cmp(node a,node b)
{
    return a.y<b.y;
}
int main()
{
	#ifndef  ONLINE_JUDGE
	freopen("code/in.txt","r",stdin);
  #endif

	scanf("%d",&n);
	if (n==1)
	{
	    puts("0");
	    return  0;
	}
	for ( int i  = 0 ; i < n ; i++) scanf("%I64d %I64d",&p[i].x,&p[i].y);
	sort(p,p+n);

	a = 0 ;
	b = 0 ;
	c = 0 ;
	for ( int i = 0 ; i < n-1 ; i++)
	{
	    if (p[i].x==p[i+1].x)
	    {
		a++;
		if (p[i].y==p[i+1].y) c++;
	    }
	}

	sort(p,p+n,cmp);

	for ( int i = 0 ; i< n-1 ; i++)
	{
	    if (p[i].y==p[i+1].y)
		b++;
	}

	LL ans =0LL;
	ans = ans +cal(a)+cal(b)-cal(c);
	cout<<ans<<endl;

  #ifndef ONLINE_JUDGE
  fclose(stdin);
  #endif
    return 0;
}


/* ***********************************************
Author :111qqz
Created Time :2016年03月07日 星期一 18时43分02秒
File Name :code/C.cpp
************************************************ */

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define fst first
#define sec second
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define ms(a,x) memset(a,x,sizeof(a))
typedef long long LL;
#define pi pair < int ,int >
#define MP make_pair

using namespace std;
const double eps = 1E-8;
const int dx4[4]={1,0,0,-1};
const int dy4[4]={0,-1,1,0};
const int inf = 0x3f3f3f3f;
const int N=2E6+7;

struct node
{
    int x,y;

    bool operator < (node b)const
    {
	if (x==b.x) return y<b.y;
	return x<b.x;
    }
}p[N];

bool cmp( node a,node b)
{
    return a.y<b.y;
}
LL cal( LL x)
{
    LL res = x*(x+1)/2;
    return res;
}
int n;
LL a,b,c;
LL cnta,cntb,cntc;
int main()
{
	#ifndef  ONLINE_JUDGE
	freopen("code/in.txt","r",stdin);
  #endif

	ios::sync_with_stdio(false);
	cin>>n;
	for ( int i = 1 ;i  <= n ; i++) cin>>p[i].x>>p[i].y;

	sort(p+1,p+n+1);

	a=b=c=0LL;
	cnta=cntb=cntc=0LL;

	for ( int i = 1 ; i <= n-1 ; i++)
	{
	    if (p[i].x==p[i+1].x)
	    {
		cnta++;
	    }
	    else
	    {
		a+=cal(cnta);
		cnta = 0 ;
	    }
	}
	a +=cal(cnta);

	for ( int i = 1 ; i <= n-1 ; i++)
	{
	    if (p[i].x==p[i+1].x&&p[i].y==p[i+1].y)
	    {
		cntc++;
	    }
	    else
	    {
		c +=cal(cntc);
		cntc = 0 ;
	    }
	}

	c+=cal(cntc);

	sort(p+1,p+n+1,cmp);
	for ( int i =  1 ; i  <= n-1 ; i ++)
	{
	    if (p[i].y==p[i+1].y)
	    {
		cntb++;
	    }
	    else
	    {
		b +=cal(cntb);
		cntb = 0 ;
	    }
	}
	b +=cal(cntb);

	LL ans=0LL;
	ans = a+b-c;
	cout<<ans<<endl;

  #ifndef ONLINE_JUDGE
  fclose(stdin);
  #endif
    return 0;
}


#include <iostream>
#include <cstring>
#include<algorithm>
#include <cstdio>
#include <cstdlib>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int q,n,i,j,k,c[200001],d[200001];
long long ans;

struct dot{int x,y;
};
dot s[200000];
bool comparisonx(dot a,dot b){
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
bool comparisony(dot a,dot b){
if(a.y==b.y) a.x<b.x;
return a.y<b.y;
}
int main(int argc, char** argv) {
	scanf("%d",&n);
	for(i=0;i<n;i++)
	scanf("%d%d",&s[i].x,&s[i].y);
	sort(s,s+n,comparisony);
	k=s[0].y;s[0].y=0;j=0;
	for(i=1;i<n;i++)
	{
	if(s[i].y>k) {k=s[i].y;j++;}
	s[i].y=j;
	}
	sort(s,s+n,comparisonx);
    k=s[0].x;s[0].x=0;j=0;
	for(i=1;i<n;i++)
	{
	if(s[i].x>k) {k=s[i].x;j++;}
	s[i].x=j;
	}
	memset(c,0,sizeof(c));
	memset(d,0,sizeof(d));
	j=s[0].x;k=s[0].y;
	q=1;ans=0;
	c[s[0].x]++;
	d[s[0].y]++;
	for(i=1;i<n;i++)
    {
	c[s[i].x]++;
	d[s[i].y]++;
	if(s[i].x==j&&s[i].y==k)
	  {
	  q++;
	  }
	else
	  {
	  ans=ans-q*(q-1)/2;
	  j=s[i].x;k=s[i].y;
	  q=1;
	  }
	}
	ans=ans-q*(q-1)/2;
	for(i=0;i<=200000;i++)
	{
	if(c[i]>0) ans=ans+c[i]*(c[i]-1)/2;
	if(d[i]>0) ans=ans+d[i]*(d[i]-1)/2;
	}
	printf("%I64d\n",ans);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int N = (int) 5e5 + 7;
int n, q, t[N];
string s;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> q >> s;
  for (int i = 1; i <= n; i++) {
    if (s[i - 1] == '<') {
      t[i] = 1;
    } else {
      t[i] = 0;
    }
  }
  while (q--) {
    int l, r, sol = 0;
    cin >> l >> r;
    for (int i = l; i <= r; i++) {
      t[i] ^= 1;
    }
    vector<pair<int, int>> e;
    for (int i = l; i <= r; i++) {
      if (e.empty() || t[i] != e.back().first) {
        e.push_back({t[i], 0});
      }
      e.back().second++;
    }
    for (auto &it : e) {
      sol = max(sol, it.second);
    }
    for (int i = 0; i + 1 < (int) e.size(); i++) {
      if (e[i].first == 0 && e[i + 1].first == 1) {
        sol = max(sol, e[i].second + e[i + 1].second);
      }
    }
    cout << sol << "\n";
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int N = (int) 5e5 + 7;
int n, q, t[N];
string s;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  freopen ("input", "r", stdin);
  cin >> n >> q >> s;
  for (int i = 1; i <= n; i++) {
    if (s[i - 1] == '<') {
      t[i] = 1;
    } else {
      t[i] = 0;
    }
  }
  while (q--) {
    int l, r, sol = 0;
    cin >> l >> r;
    for (int i = l; i <= r; i++) {
      t[i] ^= 1;
    }
    vector<pair<int, int>> e;
    for (int i = l; i <= r; i++) {
      if (e.empty() || t[i] != e.back().first) {
        e.push_back({t[i], 0});
      }
      e.back().second++;
    }
    for (auto &it : e) {
      sol = max(sol, it.second);
    }
    for (int i = 0; i + 1 < (int) e.size(); i++) {
      if (e[i].first == 0 && e[i + 1].first == 1) {
        sol = max(sol, e[i].second + e[i + 1].second);
      }
    }
    cout << sol << "\n";
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int N = (int) 5e5 + 7;
int n, q, val[N];
string s;

struct T {
  int len; /// 1
  int sol01; /// 2
  int sol10; /// 3
  int first; /// 4
  int last; /// 5
  int len_first; /// 6
  int len_last; /// 7
  int len_first2; /// 8
  int len_last2; /// 9

};

T operator + (T a, T b) {
  if (a.len == -1) {
    return b;
  }
  if (b.len == -1) {
    return a;
  }
  int len = a.len + b.len; /// 1

  int sol01 = max(a.sol01, b.sol01); /// 2
  if (a.last == 0) {
    sol01 = max(sol01, a.len_last + b.len_first);
  }
  if (a.last == 1) {
    if (b.first == 1) {
      sol01 = max(sol01, a.len_last2 + a.len_last + b.len_first);
    }
  } else {
    if (b.first == 1) {
      sol01 = max(sol01, a.len_last + b.len_first);
    } else {
      sol01 = max(sol01, a.len_last + b.len_first + b.len_first2);
    }
  }
  int sol10 = max(a.sol10, b.sol10); /// 3
  if (a.last == 1) {
    sol10 = max(sol10, a.len_last + b.len_first);
  }
  if (a.last == 0) {
    if (b.first == 0) {
      sol10 = max(sol10, a.len_last2 + a.len_last + b.len_first);
    }
  } else {
    if (b.first == 0) {
      sol10 = max(sol10, a.len_last + b.len_first);
    } else {
      sol10 = max(sol10, a.len_last + b.len_first + b.len_first2);
    }
  }

  int first = a.first; /// 4
  int last = b.last; /// 5
  int len_first = a.len_first + (a.len_first == a.len && b.first == a.first) * b.len_first; /// 6
  int len_last = b.len_last + (b.len_last == b.len && b.last == a.last) * a.len_last; /// 7
  int len_first2; /// 8
  if (a.len_first2 == 0) {
    if (a.first != b.first) {
      len_first2 = b.len_first;
    } else {
      len_first2 = b.len_first2;
    }
  } else {
    len_first2 = a.len_first2 + (a.len_first + a.len_first2 == a.len && a.last == b.first) * b.first;
  }
  int len_last2; /// 9
  if (b.len_last2 == 0) {
    if (a.last != b.first) {
      len_last2 = a.len_last;
    } else {
      len_last2 = a.len_last2;
    }
  } else {
    len_last2 = b.len_last2 + (b.len_last + b.len_last2 == b.len && a.last == b.first) * a.len_last;
  }
  return {len, sol01, sol10, first, last, len_first, len_last, len_first2, len_last2};
}

T t[4 * N];
bool inv[4 * N];

void build(int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = {1, 1, 1, val[tl], val[tl], 1, 1, 0, 0};
    return;
  }
  int tm = (tl + tr) / 2;
  build(2 * v, tl, tm);
  build(2 * v + 1, tm + 1, tr);
  t[v] = t[2 * v] + t[2 * v + 1];
}

void push(int v, int tl, int tr) {
  if (inv[v]) {
    swap(t[v].sol01, t[v].sol10);
    t[v].first ^= 1;
    t[v].last ^= 1;
    if (tl < tr) {
      inv[2 * v] ^= 1;
      inv[2 * v + 1] ^= 1;
    }
    inv[v] ^= 1;
  }
}

void upd(int v, int tl, int tr, int l, int r) {
  push(v, tl, tr);
  if (tr < l || r < tl) {
    return;
  }
  if (l <= tl && tr <= r) {
    inv[v] ^= 1;
    push(v, tl, tr);
    return;
  }
  int tm = (tl + tr) / 2;
  upd(2 * v, tl, tm, l, r);
  upd(2 * v + 1, tm + 1, tr, l, r);
  t[v] = t[2 * v] + t[2 * v + 1];
}

T get(int v, int tl, int tr, int l, int r) {
  push(v, tl, tr);
  if (tr < l || r < tl) {
    T ret;
    ret.len = -1;
    return ret;
  }
  if (l <= tl && tr <= r) {
    return t[v];
  }
  int tm = (tl + tr) /2 ;
  return get(2 * v, tl, tm, l, r) + get(2 * v + 1, tm + 1, tr, l, r);
}

void upd(int l, int r) {
  upd(1, 1, n, l, r);
}

int get(int l, int r) {
  return get(1, 1, n, l, r).sol01;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> q >> s;
  for (int i = 1; i <= n; i++) {
    if (s[i - 1] == '<') {
      val[i] = 1;
    } else {
      val[i] = 0;
    }
  }
  build(1, 1, n);
  while (q--) {
    int l, r;
    cin >> l >> r;
    upd(l, r);
    cout << get(l, r) << "\n";
  }
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int N = (int) 5e5 + 7;
int n, q, val[N];
string s;

struct Data {
  int sol0, sol1, sol01, sol10, len, pre0, pre1, suf0, suf1;
};

Data et;
int lazy[4 * N];
Data segt[4 * N];

Data operator + (Data a, Data b) {
  if (a.len == -1) {
    return b;
  }
  if (b.len == -1) {
    return a;
  }
  int sol0 = max(a.suf0 + b.pre0, max(a.sol0, b.sol0));
  int sol1 = max(a.suf1 + b.pre1, max(a.sol1, b.sol1));

  int sol01 = max(a.suf0 + b.pre1, max(a.sol01, b.sol01));
  int sol10 = max(a.suf1 + b.pre0, max(a.sol10, b.sol10));
  sol01 = max(sol01, a.sol01 + b.pre1);
  sol01 = max(sol01, a.suf0 + b.sol01);

  sol10 = max(sol10, a.sol10 + b.pre0);
  sol10 = max(sol10, a.suf1 + b.sol10);

  int len = a.len + b.len;
  int pre0 = a.pre0 + (a.pre0 == a.len) * b.pre0;
  int pre1 = a.pre1 + (a.pre1 == a.len) * b.pre1;

  int suf0 = b.suf0 + (b.suf0 == b.len) * a.suf0;
  int suf1 = b.suf1 + (b.suf1 == b.len) * a.suf1;
  return {sol0, sol1, sol01, sol10, len, pre0, pre1, suf0, suf1};
}

void push(int v, int tl, int tr) {
  if (lazy[v]) {
    if (tl < tr) {
      lazy[2 * v] ^= 1;
      lazy[2 * v + 1] ^= 1;
    }
    swap(segt[v].sol0, segt[v].sol1);
    swap(segt[v].sol01, segt[v].sol10);
    swap(segt[v].pre0, segt[v].pre1);
    swap(segt[v].suf0, segt[v].suf1);
    lazy[v] ^= 1;
  }
}

void build(int v, int tl, int tr) {
  if (tl == tr) {
    segt[v] = {(val[tl] == 0), (val[tl] == 1), 0, 0, 1, (val[tl] == 0), (val[tl] == 1), (val[tl] == 0), (val[tl] == 1)};
  } else {
    int tm = (tl + tr) / 2;
    build(2 * v, tl, tm);
    build(2 * v + 1, tm + 1, tr);
    segt[v] = segt[2 * v] + segt[2 * v + 1];
  }
}

void inv(int v, int tl, int tr, int l, int r) {
  push(v, tl, tr);
  if (tr < l || r < tl) {
    return;
  }
  if (l <= tl && tr <= r) {
    lazy[v] ^= 1;
    push(v, tl, tr);
    return;
  }
  int tm = (tl + tr) / 2;
  inv(2 * v, tl, tm, l, r);
  inv(2 * v + 1, tm + 1, tr, l, r);
  segt[v] = segt[2 * v] + segt[2 * v + 1];
}

Data get(int v, int tl, int tr, int l, int r) {
  push(v, tl, tr);
  if (tr < l || r < tl) {
    return et;
  }
  if (l <= tl && tr <= r) {
    return segt[v];
  }
  int tm = (tl + tr) / 2;
  return get(2 * v, tl, tm, l, r) + get(2 * v + 1, tm + 1, tr, l, r);
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  et.len = -1;
  cin >> n >> q >> s;
  for (int i = 1; i <= n; i++) {
    if (s[i - 1] == '<') {
      val[i] = 1;
    } else {
      val[i] = 0;
    }
  }
  build(1, 1, n);
  while (q--) {
    int l, r;
    cin >> l >> r;
    inv(1, 1, n, l, r);
    Data it = get(1, 1, n, l, r);
    int sol = max(it.sol01, max(it.sol0, it.sol1));
    cout << sol << "\n";
  }
  return 0;
}


/*      ~Botay~        *
 *  code by kazalika   */
#include <bits/stdc++.h>
using namespace std;

struct node {
  int l0, l1, r0, r1, l10, r10, l01, r01, mx0, mx1, mx10, mx01, len, chng;
};

struct segtree {
  int size;
  vector<node> tr;

  node merge(node a, node b) {
    if (!a.len)
      return b;
    if (!b.len)
      return a;
    node rt;

    //chng
    rt.chng = 0;

    //len
    rt.len = a.len + b.len;

    //l0
    rt.l0 = a.l0;
    if (a.l0 == a.len)
      rt.l0 += b.l0;

    //l1
    rt.l1 = a.l1;
    if (a.l1 == a.len)
      rt.l1 += b.l1;

    //r0
    rt.r0 = b.r0;
    if (b.r0 == b.len)
      rt.r0 += a.r0;

    //r1
    rt.r1 = b.r1;
    if (b.r1 == b.len)
      rt.r1 += a.r1;

    //l10
    rt.l10 = a.l10;
    if (a.l10 == a.len)
      rt.l10 += b.l0;
    if (a.l1 == a.len)
      rt.l10 = max({rt.l10, a.l1 + b.l0, a.l1 + b.l10});

    //r10
    rt.r10 = b.r10;
    if (b.r10 == b.len)
      rt.r10 += a.r1;
    if (b.r0 == b.len)
      rt.r10 = max({rt.r10, a.r10 + b.r0, a.r1 + b.r0});

    //l01
    rt.l01 = a.l01;
    if (a.l01 == a.len)
      rt.l01 += b.l1;
    if (a.l0 == a.len)
      rt.l01 = max({rt.l01, a.l0 + b.l1, a.l0 + b.l01});

    //r01
    rt.r01 = b.r01;
    if (b.r01 == b.len)
      rt.r01 += a.r0;
    if (b.r1 == b.len)
      rt.r01 = max({rt.r01, a.r01 + b.r1, a.r0 + b.r1});

    //mx0
    rt.mx0 = max({a.mx0, b.mx0, a.r0 + b.l0});

    //mx1
    rt.mx1 = max({a.mx1, b.mx1, a.r1 + b.l1});

    //mx10
    rt.mx10 = max({a.mx10, b.mx10, rt.l10, rt.r10, a.r10 + b.l0, a.r1 + b.l10});

    //mx01
    rt.mx01 = max({a.mx01, b.mx01, rt.l01, rt.r01, a.r01 + b.l1, a.r0 + b.l01});

    return rt;
  }

  void push(int t) {
    if (!tr[t].chng)
      return;
    swap(tr[t].l0, tr[t].l1);
    swap(tr[t].r0, tr[t].r1);
    swap(tr[t].l10, tr[t].l01);
    swap(tr[t].r10, tr[t].r01);
    swap(tr[t].mx0, tr[t].mx1);
    swap(tr[t].mx10, tr[t].mx01);
    if (tr[t].len > 1) {
      tr[t * 2 + 1].chng ^= 1;
      tr[t * 2 + 2].chng ^= 1;
    }
    tr[t].chng = 0;
  }

  void build(int t, int l, int r, vector<int> &v) {
    if (l + 1 == r) {
      if (v[l])
        tr[t] = {0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0};
      else
        tr[t] = {1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0};
      return;
    }
    int md = r + l >> 1;
    build(t * 2 + 1, l, md, v);
    build(t * 2 + 2, md, r, v);
    tr[t] = merge(tr[t * 2 + 1], tr[t * 2 + 2]);
  }
  segtree(vector<int> &v) : size(v.size()) {
    tr.resize(4 * size);
    build(0, 0, size, v);
  }

  void upd(int t, int l, int r, int x, int y) {
    push(t);
    if (l >= x && r <= y) {
      tr[t].chng ^= 1;
      push(t);
      return;
    }
    if (l >= y || r <= x)
      return;
    int md = r + l >> 1;
    upd(t * 2 + 1, l, md, x, y);
    upd(t * 2 + 2, md, r, x, y);
    tr[t] = merge(tr[t * 2 + 1], tr[t * 2 + 2]);
  }
  void upd(int l, int r) {
    upd(0, 0, size, l, r + 1);
  }

  node get(int t, int l, int r, int x, int y) {
    push(t);
    if (l >= x && r <= y)
      return tr[t];
    if (l >= y || r <= x)
      return {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    int md = r + l >> 1;
    return merge(get(t * 2 + 1, l, md, x, y), get(t * 2 + 2, md, r, x, y));
  }
  int get(int l, int r) {
    node rt = get(0, 0, size, l, r + 1);
    return rt.mx10;
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int n, q;
  cin >> n >> q;
  string s;
  cin >> s;
  vector<int> v(n);
  for (int i = 0; i < n; ++i)
    v[i] = (s[i] == '>' ? 1 : 0);
  segtree st(v);
  for (int i = 0; i < q; ++i) {
    int l, r;
    cin >> l >> r;
    l--, r--;
    st.upd(l, r);
    int g = st.get(l, r);
    cout << g << '\n';
  }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define REP(k, n) for (ll k = 0; k < (ll)(n); ++k)
#define REPREV(k, n) for (ll k = (ll)(n)-1; k >= 0; --k)
#define FOR(k, a, b) for (ll k = (ll)(a); k < (ll)(b); ++k)
#define FORREV(k, a, b) for (ll k = (ll)(b)-1; k >= (ll)(a); --k)
#define FOREACH(e, v) for (auto& e : v)

#define TGET(t, i) get<i>(t)
#define TSET(t, i, a) get<i>(t) = a
// MinHeap - priority_queue<ll, vll, greater<ll>> pq;

#define EVEN(n) ((n)&1) == 0
#define ODD(n) ((n)&1) == 1

#define SORT(v) sort(v.begin(), v.end())
#define SORTREV(v) sort(v.rbegin(), v.rend())
#define SHUFFLE(v) random_shuffle(v.begin(), v.end())
//srand(unsigned(time(0)));

#define REMOVEAT(v, i) v.erase(v.begin() + i)
#define REVERSE(v) reverse(v.begin(), v.end())

ll MOD(ll x, ll m) {
    ll r = x % m;
    if (r < 0) {
        r += m;
    }
    return r;
}

ostream& operator<<(ostream& str, const pll& 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";
}

#define POS "POSSIBLE"
#define IMPOS "IMPOSSIBLE"

// #define INF LLONG_MAX
// #define MINF LLONG_MIN
#define INF 9e18
#define MINF -INF

struct SegmentTree {
    struct TreeNode {
        ll __prefix0 = 0;
        ll __prefix1 = 0;
        ll __prefix01 = 0;
        ll __prefix10 = 0;
        ll __suffix0 = 0;
        ll __suffix1 = 0;
        ll __suffix10 = 0;
        ll __suffix01 = 0;
        ll __max01 = 0;
        ll __max10 = 0;
        ll __max1 = 0;
        ll __max0 = 0;

        ll __size = 0;

        ll __pendingDelta = 0;
        pll __pendingOverwrite = {0, 0};

        TreeNode() {
        }

        TreeNode(ll x, ll i) {
            init(x, i);
        }

        void init(ll x, ll 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;
        }

        vll 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 += n2.__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 += n2.__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);
            res.__max01 = max(res.__max01, n1.__suffix0 + n2.__prefix1);
            res.__max01 = max(res.__max01, n1.__suffix0 + n2.__prefix01);
            res.__max01 = max(res.__max01, n1.__suffix01 + n2.__prefix1);

            res.__max10 = max(n1.__max10, n2.__max10);
            res.__max10 = max(res.__max10, n1.__suffix1 + n2.__prefix0);
            res.__max10 = max(res.__max10, n1.__suffix1 + n2.__prefix10);
            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;
    ll __n;

    SegmentTree(ll n) : __n(n) {
        vll arr(n);
        __tree = vector<TreeNode>(arr.size() * 4);
        init(0, arr.size() - 1, 0, arr);
    }

    SegmentTree(vector<ll> arr) {
        __tree = vector<TreeNode>(arr.size() * 4);
        __n = arr.size();
        init(0, arr.size() - 1, 0, arr);
    }

    vll query(ll l, ll r) {
        assert(l <= r && l >= 0 && r < __n);
        return queryHelper(0, __n - 1, 0, l, r).result();
    }

    TreeNode queryHelper(ll s, ll e, ll i, ll l, ll r) {
        applyPendingChanges(s, e, i);
        if (l == s && r == e) {
            return __tree[i];
        }

        ll 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(ll s, ll e, ll i, ll l, ll r, ll 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;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll lidx = SegmentTree::leftIdx(i);
        ll 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(ll l, ll r, ll v) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n - 1, 0, l, r, v, false);
    }

    void addToRange(ll l, ll r, ll d) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n - 1, 0, l, r, d, true);
    }

    void add(ll i, ll d) {
        addToRange(i, i, d);
    }

    void update(ll i, ll v) {
        updateRange(i, i, v);
    }

    void init(ll s, ll e, ll i, vector<ll>& arr) {
        assert(s <= e && i < __tree.size());
        if (s == e) {
            __tree[i].init(arr[s], s);
            return;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll l = SegmentTree::leftIdx(i);
        ll 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(ll s, ll e, ll j) {
        TreeNode& treeNode = __tree[j];
        pll pendingOverwrite = treeNode.__pendingOverwrite;
        ll 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);
            }
            treeNode.__pendingDelta = 0;
        }

        if (s == e || !pendingOverwrite.first && !pendingDelta)
            return;

        ll l = SegmentTree::leftIdx(j);
        ll 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 ll leftIdx(ll i) {
        return i * 2 + 1;
    }

    static ll rightIdx(ll i) {
        return i * 2 + 2;
    }

    static ll middleIdx(ll s, ll e) {
        return (s + e) / 2;
    }
};

void solve() {
    ll n, q;
    cin >> n >> q;
    string s;
    cin >> s;

    vector<ll> pro_s(n);
    REP(i, n) {
        if (s[i] == '<') {
            pro_s[i] = 1;
        } else {
            pro_s[i] = 0;
        }
    }
    SegmentTree st(pro_s);

    REP(i, q) {
        ll l, r;
        cin >> l >> r;
        l--;
        r--;
        st.addToRange(l, r, 1);
        vll 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;
    // cin >> tt;
    for (int t = 1; t <= tt; t++) {
        // cout << "Case #" << t << ": ";
        solve();
    }
    //cin.rdbuf()->in_avail()
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define REP(k, n) for (ll k = 0; k < (ll)(n); ++k)
#define REPREV(k, n) for (ll k = (ll)(n)-1; k >= 0; --k)
#define FOR(k, a, b) for (ll k = (ll)(a); k < (ll)(b); ++k)
#define FORREV(k, a, b) for (ll k = (ll)(b)-1; k >= (ll)(a); --k)
#define FOREACH(e, v) for (auto& e : v)

#define TGET(t, i) get<i>(t)
#define TSET(t, i, a) get<i>(t) = a
// MinHeap - priority_queue<ll, vll, greater<ll>> pq;

#define EVEN(n) ((n)&1) == 0
#define ODD(n) ((n)&1) == 1

#define SORT(v) sort(v.begin(), v.end())
#define SORTREV(v) sort(v.rbegin(), v.rend())
#define SHUFFLE(v) random_shuffle(v.begin(), v.end())
//srand(unsigned(time(0)));

#define REMOVEAT(v, i) v.erase(v.begin() + i)
#define REVERSE(v) reverse(v.begin(), v.end())

ll MOD(ll x, ll m) {
    ll r = x % m;
    if (r < 0) {
        r += m;
    }
    return r;
}

ostream& operator<<(ostream& str, const pll& 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";
}

#define POS "POSSIBLE"
#define IMPOS "IMPOSSIBLE"

// #define INF LLONG_MAX
// #define MINF LLONG_MIN
#define INF 9e18
#define MINF -INF

struct SegmentTree {
    struct TreeNode {
        ll __prefix0 = 0;
        ll __prefix1 = 0;
        ll __prefix01 = 0;
        ll __prefix10 = 0;
        ll __suffix0 = 0;
        ll __suffix1 = 0;
        ll __suffix10 = 0;
        ll __suffix01 = 0;
        ll __max01 = 0;
        ll __max10 = 0;
        ll __max1 = 0;
        ll __max0 = 0;

        ll __size = 0;

        ll __pendingDelta = 0;
        pll __pendingOverwrite = {0, 0};

        TreeNode() {
        }

        TreeNode(ll x, ll i) {
            init(x, i);
        }

        void init(ll x, ll 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;
        }

        vll 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;
    ll __n;

    SegmentTree(ll n) : __n(n) {
        vll arr(n);
        __tree = vector<TreeNode>(arr.size() * 4);
        init(0, arr.size() - 1, 0, arr);
    }

    SegmentTree(vector<ll> arr) {
        __tree = vector<TreeNode>(arr.size() * 4);
        __n = arr.size();
        init(0, arr.size() - 1, 0, arr);
    }

    vll query(ll l, ll r) {
        assert(l <= r && l >= 0 && r < __n);
        return queryHelper(0, __n - 1, 0, l, r).result();
    }

    TreeNode queryHelper(ll s, ll e, ll i, ll l, ll r) {
        applyPendingChanges(s, e, i);
        if (l == s && r == e) {
            return __tree[i];
        }

        ll 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(ll s, ll e, ll i, ll l, ll r, ll 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;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll lidx = SegmentTree::leftIdx(i);
        ll 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(ll l, ll r, ll v) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n - 1, 0, l, r, v, false);
    }

    void addToRange(ll l, ll r, ll d) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n - 1, 0, l, r, d, true);
    }

    void add(ll i, ll d) {
        addToRange(i, i, d);
    }

    void update(ll i, ll v) {
        updateRange(i, i, v);
    }

    void init(ll s, ll e, ll i, vector<ll>& arr) {
        assert(s <= e && i < __tree.size());
        if (s == e) {
            __tree[i].init(arr[s], s);
            return;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll l = SegmentTree::leftIdx(i);
        ll 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(ll s, ll e, ll j) {
        TreeNode& treeNode = __tree[j];
        pll pendingOverwrite = treeNode.__pendingOverwrite;
        ll 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;

        ll l = SegmentTree::leftIdx(j);
        ll 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 ll leftIdx(ll i) {
        return i * 2 + 1;
    }

    static ll rightIdx(ll i) {
        return i * 2 + 2;
    }

    static ll middleIdx(ll s, ll e) {
        return (s + e) / 2;
    }
};

void solve() {
    ll n, q;
    cin >> n >> q;
    string s;
    cin >> s;

    vector<ll> pro_s(n);
    REP(i, n) {
        if (s[i] == '<') {
            pro_s[i] = 1;
        } else {
            pro_s[i] = 0;
        }
    }
    SegmentTree st(pro_s);

    REP(i, q) {
        ll l, r;
        cin >> l >> r;
        l--;
        r--;
        st.addToRange(l, r, 1);
        vll 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;
    // cin >> tt;
    for (int t = 1; t <= tt; t++) {
        // cout << "Case #" << t << ": ";
        solve();
    }
    //cin.rdbuf()->in_avail()
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define REP(k, n) for (ll k = 0; k < (ll)(n); ++k)
#define REPREV(k, n) for (ll k = (ll)(n)-1; k >= 0; --k)
#define FOR(k, a, b) for (ll k = (ll)(a); k < (ll)(b); ++k)
#define FORREV(k, a, b) for (ll k = (ll)(b)-1; k >= (ll)(a); --k)
#define FOREACH(e, v) for (auto& e : v)

#define TGET(t, i) get<i>(t)
#define TSET(t, i, a) get<i>(t) = a
// MinHeap - priority_queue<ll, vll, greater<ll>> pq;

#define EVEN(n) ((n)&1) == 0
#define ODD(n) ((n)&1) == 1

#define SORT(v) sort(v.begin(), v.end())
#define SORTREV(v) sort(v.rbegin(), v.rend())
#define SHUFFLE(v) random_shuffle(v.begin(), v.end())
//srand(unsigned(time(0)));

#define REMOVEAT(v, i) v.erase(v.begin() + i)
#define REVERSE(v) reverse(v.begin(), v.end())

ll MOD(ll x, ll m) {
    ll r = x % m;
    if (r < 0) {
        r += m;
    }
    return r;
}

ostream& operator<<(ostream& str, const pll& 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";
}

#define POS "POSSIBLE"
#define IMPOS "IMPOSSIBLE"

// #define INF LLONG_MAX
// #define MINF LLONG_MIN
#define INF 9e18
#define MINF -INF

struct SegmentTree {
    struct TreeNode {
        ll __prefix0 = 0;
        ll __prefix1 = 0;
        ll __prefix01 = 0;
        ll __prefix10 = 0;
        ll __suffix0 = 0;
        ll __suffix1 = 0;
        ll __suffix10 = 0;
        ll __suffix01 = 0;
        ll __max01 = 0;
        ll __max10 = 0;

        ll __size = 0;

        ll __pendingDelta = 0;
        pll __pendingOverwrite = {0, 0};

        TreeNode() {
        }

        TreeNode(ll x, ll i) {
            init(x, i);
        }

        void init(ll x, ll 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;
            __size = 1;
        }

        vll result() {
            return {__max01, __prefix0, __prefix1};
        }

        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 += n2.__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 += n2.__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);
            res.__max01 = max(res.__max01, n1.__suffix0 + n2.__prefix1);
            res.__max01 = max(res.__max01, n1.__suffix0 + n2.__prefix01);
            res.__max01 = max(res.__max01, n1.__suffix01 + n2.__prefix1);

            res.__max10 = max(n1.__max10, n2.__max10);
            res.__max10 = max(res.__max10, n1.__suffix1 + n2.__prefix0);
            res.__max10 = max(res.__max10, n1.__suffix1 + n2.__prefix10);
            res.__max10 = max(res.__max10, n1.__suffix10 + n2.__prefix0);

            res.__size = n1.__size + n2.__size;
            return res;
        }
    };

    vector<TreeNode> __tree;
    ll __n;

    SegmentTree(ll n) : __n(n) {
        vll arr(n);
        __tree = vector<TreeNode>(arr.size() * 4);
        init(0, arr.size() - 1, 0, arr);
    }

    SegmentTree(vector<ll> arr) {
        __tree = vector<TreeNode>(arr.size() * 4);
        __n = arr.size();
        init(0, arr.size() - 1, 0, arr);
    }

    vll query(ll l, ll r) {
        assert(l <= r && l >= 0 && r < __n);
        return queryHelper(0, __n - 1, 0, l, r).result();
    }

    TreeNode queryHelper(ll s, ll e, ll i, ll l, ll r) {
        applyPendingChanges(s, e, i);
        if (l == s && r == e) {
            return __tree[i];
        }

        ll 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(ll s, ll e, ll i, ll l, ll r, ll 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;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll lidx = SegmentTree::leftIdx(i);
        ll 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(ll l, ll r, ll v) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n - 1, 0, l, r, v, false);
    }

    void addToRange(ll l, ll r, ll d) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n - 1, 0, l, r, d, true);
    }

    void add(ll i, ll d) {
        addToRange(i, i, d);
    }

    void update(ll i, ll v) {
        updateRange(i, i, v);
    }

    void init(ll s, ll e, ll i, vector<ll>& arr) {
        assert(s <= e && i < __tree.size());
        if (s == e) {
            __tree[i].init(arr[s], s);
            return;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll l = SegmentTree::leftIdx(i);
        ll 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(ll s, ll e, ll j) {
        TreeNode& treeNode = __tree[j];
        pll pendingOverwrite = treeNode.__pendingOverwrite;
        ll 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);
            }
            treeNode.__pendingDelta = 0;
        }

        if (s == e || !pendingOverwrite.first && !pendingDelta)
            return;

        ll l = SegmentTree::leftIdx(j);
        ll 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 ll leftIdx(ll i) {
        return i * 2 + 1;
    }

    static ll rightIdx(ll i) {
        return i * 2 + 2;
    }

    static ll middleIdx(ll s, ll e) {
        return (s + e) / 2;
    }
};

void solve() {
    ll n, q;
    cin >> n >> q;
    string s;
    cin >> s;

    vector<ll> pro_s(n);
    REP(i, n) {
        if (s[i] == '<') {
            pro_s[i] = 1;
        } else {
            pro_s[i] = 0;
        }
    }
    SegmentTree st(pro_s);

    REP(i, q) {
        ll l, r;
        cin >> l >> r;
        l--;
        r--;
        st.addToRange(l, r, 1);
        vll 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;
    // cin >> tt;
    for (int t = 1; t <= tt; t++) {
        // cout << "Case #" << t << ": ";
        solve();
    }
    //cin.rdbuf()->in_avail()
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <utility>
#include <tuple>
using namespace std;

typedef long long ll;
typedef vector<char> vc;

struct Node {
    Node *l = 0, *r = 0;
    int lo, hi;
    bool flipBelow = false;
    char c = ' ';
    int mG = 0, mFG = 0;
    int mLL = 0, mLR = 0, mRL = 0, mRR = 0, mLLR = 0, mLRL = 0, mRLR = 0, mRRL = 0;
    Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of −in f
    Node(string& s, int lo, int hi) : lo(lo), hi(hi) {
        if (lo + 1 < hi) {
            int mid = lo + (hi - lo)/2;
            l = new Node(s, lo, mid); r = new Node(s, mid, hi);
        }
        else {
            c = s[lo];
        }
        fillMetadata();

    }

    int size() {
        return hi - lo;
    }

    int size(int L, int R) {
        if (R <= lo || L >= hi) return 0;
        if (L >= lo && R <= hi) return R - L;
        if (L < lo) {
            return min(R, hi) - lo;
        }
        if (R > hi) {
            return hi - max(L, lo);
        }
    }

    void fillMetadata() {
        if (size() == 1) {
            if (c == '<') {
                mLL = 1, mRL = 1, mLLR = 1, mRLR = 1;
            } else {
                mLR = 1, mRR = 1, mLRL = 1, mRRL = 1;
            }
            mG = 1, mFG = 1;
        } else {
            if (r->mRR == r->size()) {
                mRR = r->mRR + l->mRR;
            } else {
                mRR = r->mRR;
            }

            if (r->mRL == r->size()) {
                mRL = r->mRL + l->mRL;
            } else {
                mRL = r->mRL;
            }

            if (l->mLR == l->size()) {
                mLR = l->mLR + r->mLR;
            } else {
                mLR = l->mLR;
            }

            if (l->mLL == l->size()) {
                mLL = l->mLL + r->mLL;
            } else {
                mLL = l->mLL;
            }

            if (r->mRRL == r->size()) {
                if (r->mRR == r->size()) {
                    mRRL = r->mRR + max(l->mRRL, l->mRL);
                } else {
                    mRRL = r->mRRL + l->mRL;
                }
            } else {
                mRRL = r->mRRL;
            }

            if (r->mRLR == r->size()) {
                if (r->mRL == r->size()) {
                    mRLR = r->mRL + max(l->mRLR, l->mRR);
                } else {
                    mRLR = r->mRLR + l->mRR;
                }
            } else {
                mRLR = r->mRLR;
            }

            if (l->mLRL == l->size()) {
                if (l->mLR == l->size()) {
                    mLRL = l->mLR + max(r->mLRL, r->mLL);
                } else {
                    mLRL = l->mLRL + r->mLL;
                }
            } else {
                mLRL = l->mLRL;
            }

            if (l->mLLR == l->size()) {
                if (l->mLL == l->size()) {
                    mLLR = l->mLL + max(r->mLLR, r->mLR);
                } else {
                    mLLR = l->mLLR + r->mLR;
                }
            } else {
                mLLR = l->mLLR;
            }

            mG = max(l->mG, r->mG);
            mG = max(mG, mLRL);
            mG = max(mG, mRLR);
            mG = max(mG, mLL);
            mG = max(mG, mRR);
            mG = max(mG, l->mRLR + r->mLL);
            mG = max(mG, l->mRR + r->mLRL);
            mG = max(mG, l->mRR + r->mLL);

            mFG = max(l->mFG, r->mFG);
            mFG = max(mFG, mLLR);
            mFG = max(mFG, mRRL);
            mFG = max(mFG, mLR);
            mFG = max(mFG, mRL);
            mFG = max(mFG, l->mRRL + r->mLR);
            mFG = max(mFG, l->mRL + r->mLLR);
            mFG = max(mFG, l->mRL + r->mLR);
        }
    }

    tuple<int, int, int, int, int, int, int, int, int> query(int L, int R) {

        //cout << "meta " << lo << " " << hi << " " << mLL << " " << mLR << " " << mRL << " " << mRR
        //     << " " << mLLR << " " << mLRL << " " << mRLR << " " << mRRL << " " << mG << "\n";
        if (R <= lo || hi <= L) return make_tuple(-1, -1, -1, -1, -1, -1, -1, -1, -1);
        if (L <= lo && hi <= R) return make_tuple(mG, mLL, mLR, mRL, mRR, mLLR, mLRL, mRLR, mRRL);
        push();
        auto lT = l->query(L, R);
        auto rT = r->query(L, R);
        if (get<0>(lT) == -1) return rT;
        if (get<0>(rT) == -1) return lT;

        int lmG = get<0>(lT), lmLL = get<1>(lT), lmLR = get<2>(lT), lmRL = get<3>(lT),
            lmRR = get<4>(lT), lmLLR = get<5>(lT), lmLRL = get<6>(lT), lmRLR = get<7>(lT),
            lmRRL = get<8>(lT);

        int rmG = get<0>(rT), rmLL = get<1>(rT), rmLR = get<2>(rT), rmRL = get<3>(rT),
            rmRR = get<4>(rT), rmLLR = get<5>(rT), rmLRL = get<6>(rT), rmRLR = get<7>(rT),
            rmRRL = get<8>(rT);

        int cmG, cmLL, cmLR, cmRL, cmRR, cmLLR, cmLRL, cmRLR, cmRRL;
        if (rmRR == r->size(L, R)) {
            cmRR = rmRR + lmRR;
        } else {
            cmRR = rmRR;
        }

        if (rmRL == r->size(L, R)) {
            cmRL = rmRL + lmRL;
        } else {
            cmRL = rmRL;
        }

        if (lmLR == l->size(L, R)) {
            cmLR = lmLR + rmLR;
        } else {
            cmLR = lmLR;
        }

        if (lmLL == l->size(L, R)) {
            cmLL = lmLL + rmLL;
        } else {
            cmLL = lmLL;
        }

        if (rmRRL == r->size(L, R)) {
            if (rmRR == r->size(L, R)) {
                cmRRL = rmRR + max(lmRRL, lmRL);
            } else {
                cmRRL = rmRRL + lmRL;
            }
        } else {
            cmRRL = rmRRL;
        }

        if (rmRLR == r->size(L, R)) {
            if (rmRL == r->size(L, R)) {
                cmRLR = rmRL + max(lmRLR, lmRR);
            } else {
                cmRLR = rmRLR + lmRR;
            }
        } else {
            cmRLR = rmRLR;
        }

        if (lmLRL == l->size(L, R)) {
            if (lmLR == l->size(L, R)) {
                cmLRL = lmLR + max(rmLRL, rmLL);
            } else {
                cmLRL = lmLRL + rmLL;
            }
        } else {
            cmLRL = lmLRL;
        }

        if (lmLLR == l->size(L, R)) {
            if (lmLL == l->size(L, R)) {
                cmLLR = lmLL + max(rmLLR, rmLR);
            } else {
                cmLLR = lmLLR + rmLR;
            }
        } else {
            cmLLR = lmLLR;
        }

        cmG = max(lmG, rmG);
        cmG = max(cmG, cmLRL);
        cmG = max(cmG, cmRLR);
        cmG = max(cmG, cmLL);
        cmG = max(cmG, cmRR);
        cmG = max(cmG, lmRLR + rmLL);
        cmG = max(cmG, lmRR + rmLRL);
        cmG = max(cmG, lmRR + rmLL);

        return make_tuple(cmG, cmLL, cmLR, cmRL, cmRR, cmLLR, cmLRL, cmRLR, cmRRL);
    }

    void flip(int L, int R) {
        if (R <= lo || hi <= L) return;
        if (L <= lo && hi <= R) {
            flipMetadata();
        } else {
            push();
            l->flip(L, R);
            r->flip(L, R);
            fillMetadata();
        }
    }

    void flipMetadata() {
        flipBelow = !flipBelow;
        swap(mLL, mLR);
        swap(mRL, mRR);
        swap(mLLR, mLRL);
        swap(mRLR, mRRL);
        swap(mG, mFG);
        if (c == '<') c = '>';
        else if (c == '>') c = '<';
    }

    void push() {
        if (flipBelow) {
            l->flip(lo, hi);
            r->flip(lo, hi);
            flipBelow = false;
            fillMetadata();
        }
    }

    char findChar(int i) {
        if (lo + 1 == hi) {
            if (lo == i) {
                return c;
            } else {
                return ' ';
            }
        }
        push();
        char c1 = l->findChar(i);
        char c2 = r->findChar(i);
        if (c1 == ' ') return c2;
        return c1;
    }

    void printMetadata() {
        cout << "meta " << lo << " " << hi << " " << mLL << " " << mLR << " " << mRL << " " << mRR
             << " " << mLLR << " " << mLRL << " " << mRLR << " " << mRRL << " " << mG << "\n";
        if (l) {
            push();
            l->printMetadata();
            r->printMetadata();
        }
    }
};

int main(void) {
    int n, q;
    cin >> n >> q;
    string s;
    cin >> s;
    Node* v = new Node(s, 0, n);

    //for (int i = 0; i < n; i++) {
    //    cout << v->findChar(i);
    //}
    //cout << "\n";
    //v->printMetadata();
    for (int i = 0; i < q; i++) {
        int l, r;
        cin >> l >> r;
        v->flip(l - 1, r);

        //if (i == 1) {
        auto res = v->query(l - 1, r);
        cout << get<0>(res) << "\n";
        //}

        //for (int i = 0; i < n; i++) {
        //    cout << v->findChar(i);
        //}
        //cout << "\n";
        //v->printMetadata();
    }
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <utility>
#include <tuple>
using namespace std;

typedef long long ll;
typedef vector<char> vc;

struct Node {
    Node *l = 0, *r = 0;
    int lo, hi;
    bool flipBelow = false;
    char c = ' ';
    int mG = 0;
    int mLL = 0, mLR = 0, mRL = 0, mRR = 0, mLLR = 0, mLRL = 0, mRLR = 0, mRRL = 0;
    Node(int lo,int hi):lo(lo),hi(hi){} // Large interval of −in f
    Node(string& s, int lo, int hi) : lo(lo), hi(hi) {
        if (lo + 1 < hi) {
            int mid = lo + (hi - lo)/2;
            l = new Node(s, lo, mid); r = new Node(s, mid, hi);
        }
        else {
            c = s[lo];
        }
        fillMetadata();

    }

    int size() {
        return hi - lo;
    }

    int size(int L, int R) {
        if (R <= lo || L >= hi) return 0;
        if (L >= lo && R <= hi) return R - L;
        if (L < lo) {
            return min(R, hi) - lo;
        }
        if (R > hi) {
            return hi - max(L, lo);
        }
    }

    void fillMetadata() {
        if (size() == 1) {
            if (c == '<') {
                mLL = 1, mRL = 1, mLLR = 1, mRLR = 1;
            } else {
                mLR = 1, mRR = 1, mLRL = 1, mRRL = 1;
            }
            mG = 1;
        } else {
            if (r->mRR == r->size()) {
                mRR = r->mRR + l->mRR;
            } else {
                mRR = r->mRR;
            }

            if (r->mRL == r->size()) {
                mRL = r->mRL + l->mRL;
            } else {
                mRL = r->mRL;
            }

            if (l->mLR == l->size()) {
                mLR = l->mLR + r->mLR;
            } else {
                mLR = l->mLR;
            }

            if (l->mLL == l->size()) {
                mLL = l->mLL + r->mLL;
            } else {
                mLL = l->mLL;
            }

            if (r->mRRL == r->size()) {
                if (r->mRR == r->size()) {
                    mRRL = r->mRR + max(l->mRRL, l->mRL);
                } else {
                    mRRL = r->mRRL + l->mRL;
                }
            } else {
                mRRL = r->mRRL;
            }

            if (r->mRLR == r->size()) {
                if (r->mRL == r->size()) {
                    mRLR = r->mRL + max(l->mRLR, l->mRR);
                } else {
                    mRLR = r->mRLR + l->mRR;
                }
            } else {
                mRLR = r->mRLR;
            }

            if (l->mLRL == l->size()) {
                if (l->mLR == l->size()) {
                    mLRL = l->mLR + max(r->mLRL, r->mLL);
                } else {
                    mLRL = l->mLRL + r->mLL;
                }
            } else {
                mLRL = l->mLRL;
            }

            if (l->mLLR == l->size()) {
                if (l->mLL == l->size()) {
                    mLLR = l->mLL + max(r->mLLR, r->mLR);
                } else {
                    mLLR = l->mLLR + r->mLR;
                }
            } else {
                mLLR = l->mLLR;
            }

            mG = max(l->mG, r->mG);
            mG = max(mG, mLRL);
            mG = max(mG, mRLR);
            mG = max(mG, mLL);
            mG = max(mG, mRR);
            mG = max(mG, l->mRLR + r->mLL);
            mG = max(mG, l->mRR + r->mLRL);
        }
    }

    tuple<int, int, int, int, int, int, int, int, int> query(int L, int R) {
        if (R <= lo || hi <= L) return make_tuple(-1, -1, -1, -1, -1, -1, -1, -1, -1);
        if (L <= lo && hi <= R) return make_tuple(mG, mLL, mLR, mRL, mRR, mLLR, mLRL, mRLR, mRRL);
        push();
        auto lT = l->query(L, R);
        auto rT = r->query(L, R);
        if (get<0>(lT) == -1) return rT;
        if (get<1>(rT) == -1) return lT;

        int lmG = get<0>(lT), lmLL = get<1>(lT), lmLR = get<2>(lT), lmRL = get<3>(lT),
            lmRR = get<4>(lT), lmLLR = get<5>(lT), lmLRL = get<6>(lT), lmRLR = get<7>(lT),
            lmRRL = get<8>(lT);

        int rmG = get<0>(rT), rmLL = get<1>(rT), rmLR = get<2>(rT), rmRL = get<3>(rT),
            rmRR = get<4>(rT), rmLLR = get<5>(rT), rmLRL = get<6>(rT), rmRLR = get<7>(rT),
            rmRRL = get<8>(rT);

        int cmG, cmLL, cmLR, cmRL, cmRR, cmLLR, cmLRL, cmRLR, cmRRL;
        if (rmRR == r->size(L, R)) {
            cmRR = rmRR + lmRR;
        } else {
            cmRR = rmRR;
        }

        if (rmRL == r->size(L, R)) {
            cmRL = rmRL + lmRL;
        } else {
            cmRL = rmRL;
        }

        if (lmLR == l->size(L, R)) {
            cmLR = lmLR + rmLR;
        } else {
            cmLR = lmLR;
        }

        if (lmLL == l->size(L, R)) {
            cmLL = lmLL + rmLL;
        } else {
            cmLL = lmLL;
        }

        if (rmRRL == r->size(L, R)) {
            if (rmRR == r->size(L, R)) {
                cmRRL = rmRR + max(lmRRL, lmRL);
            } else {
                cmRRL = rmRRL + lmRL;
            }
        } else {
            cmRRL = rmRRL;
        }

        if (rmRLR == r->size(L, R)) {
            if (rmRL == r->size(L, R)) {
                cmRLR = rmRL + max(lmRLR, lmRR);
            } else {
                cmRLR = rmRLR + lmRR;
            }
        } else {
            cmRLR = rmRLR;
        }

        if (lmLRL == l->size(L, R)) {
            if (lmLR == l->size(L, R)) {
                cmLRL = lmLR + max(rmLRL, rmLL);
            } else {
                cmLRL = lmLRL + rmLL;
            }
        } else {
            cmLRL = lmLRL;
        }

        if (lmLLR == l->size(L, R)) {
            if (lmLL == l->size(L, R)) {
                cmLLR = lmLL + max(rmLLR, rmLR);
            } else {
                cmLLR = lmLLR + rmLR;
            }
        } else {
            cmLLR = lmLLR;
        }

        cmG = max(lmG, rmG);
        cmG = max(cmG, cmLRL);
        cmG = max(cmG, cmRLR);
        cmG = max(cmG, cmLL);
        cmG = max(cmG, cmRR);
        cmG = max(cmG, lmRLR + rmLL);
        cmG = max(cmG, lmRR + rmLRL);

        return make_tuple(cmG, cmLL, cmLR, cmRL, cmRR, cmLLR, cmLRL, cmRLR, cmRRL);
    }

    void flip(int L, int R) {
        if (R <= lo || hi <= L) return;
        if (L <= lo && hi <= R) {
            flipMetadata();
        } else {
            push();
            l->flip(L, R);
            r->flip(L, R);
            fillMetadata();
        }
    }

    void flipMetadata() {
        flipBelow = !flipBelow;
        swap(mLL, mLR);
        swap(mRL, mRR);
        swap(mLLR, mLRL);
        swap(mRLR, mRRL);
        if (c == '<') c = '>';
        else if (c == '>') c = '<';
    }

    void push() {
        if (flipBelow) {
            l->flip(lo, hi);
            r->flip(lo, hi);
            flipBelow = false;
            fillMetadata();
        }
    }

    char findChar(int i) {
        if (lo + 1 == hi) {
            if (lo == i) {
                return c;
            } else {
                return ' ';
            }
        }
        push();
        char c1 = l->findChar(i);
        char c2 = r->findChar(i);
        if (c1 == ' ') return c2;
        return c1;
    }

    void printMetadata() {
        cout << "meta " << lo << " " << hi << " " << mLL << " " << mLR << " " << mRL << " " << mRR
             << " " << mLLR << " " << mLRL << " " << mRLR << " " << mRRL << " " << mG << "\n";
        if (l) {
            push();
            l->printMetadata();
            r->printMetadata();
        }
    }
};

int main(void) {
    int n, q;
    cin >> n >> q;
    string s;
    cin >> s;
    Node* v = new Node(s, 0, n);

    //for (int i = 0; i < n; i++) {
    //    cout << v->findChar(i);
    //}
    //cout << "\n";
    //v->printMetadata();
    for (int i = 0; i < q; i++) {
        int l, r;
        cin >> l >> r;
        v->flip(l - 1, r);
        auto res = v->query(l - 1, r);
        cout << get<0>(res) << "\n";
        //for (int i = 0; i < n; i++) {
        //    cout << v->findChar(i);
        //}
        //cout << "\n";
        //v->printMetadata();
    }
}


#include <bits/stdc++.h>
using namespace std;
#define sync ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define rep(i,n) for(int i=0; i<int(n); ++i)
#define repp(i,a,n) for(int i=a; i<int(n); ++i)
#define sz(x) int((x).size())
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define mp make_pair

template<class T> std::ostream& operator<<(std::ostream& os, const std::vector<T> &input);
template<class T1,class T2> std::ostream& operator<<(std::ostream& os, const std::pair<T1,T2> &input);
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) {cerr << " " << H;debug_out(T...);}
#ifdef LOCAL
#define dbg(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define dbg(...) 42
#endif
template<class T> std::ostream& operator<<(std::ostream& os, const std::vector<T> &input){for (auto const& i: input) {os << i << " ";}return os;}
template<class T1,class T2> std::ostream& operator<<(std::ostream& os, const std::pair<T1,T2> &input){os << "(" << input.first << ", " << input.second << ')';return os;}

double startTime;
double getCurrentTime() {
	return ((double)clock() - startTime) / CLOCKS_PER_SEC;
}

typedef long long ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<pi> vp;
typedef vector<ll> vl;
typedef vector<vi> vvi;

// === temeplate ===

namespace SGT{
    #define lu (u<<1)
    #define ru (u<<1|1)
    // index range [0, n)
    const int maxn = 5e5;
    const int inf = maxn;
    int n;
    struct info{
        int max, cntL, cntR, dirL, dirR;
    };
    std::ostream& operator<<(std::ostream& os, const info &x){os << "max: " << x.max << "   cntL, cnrR: " << x.cntL << " " << x.cntR << "   dirL, dirR: " << x.dirL << " " << x.dirR;return os;}

    struct node{
        int l, r;
        bool flip;
        info val[2];
    } tree[maxn * 4];

    inline void merge_node(node &n, const node &nl, const node &nr){
        n.flip = 0;
        if (nl.l >= nl.r){
            // left is empty
            rep(i,2) n.val[i] = nr.val[i];
            n.l = nr.l;
            n.r = nr.r;
            return;
        }
        if (nr.l >= nr.r){
            // right is empty
            rep(i,2) n.val[i] = nl.val[i];
            n.l = nl.l;
            n.r = nl.r;
            return;
        }

        n.l = nl.l, n.r = nr.r;

        rep(i,2){
            info &vu = n.val[i];
            const info &vl = nl.val[i];
            const info &vr = nr.val[i];

            vu.max = max(vl.max, vr.max);
            if(vl.dirR == 0 && vr.dirL == 1){
                // [... <][> ...]
            }else{
                vu.max = max(vu.max, vl.cntR + vr.cntL);
            }

            vu.cntL = vl.cntL; vu.dirL = vl.dirL;
            vu.cntR = vr.cntR; vu.dirR = vr.dirR;

            if(vl.cntL == nl.r - nl.l && !(vl.dirR == 0 && vr.dirL == 1)){
                // [>><<][<<..]
                vu.cntL = vl.cntL + vr.cntL;
            }

            if(vr.cntR == nr.r - nr.l && !(vl.dirR == 0 && vr.dirL == 1)){
                // [..>>][>><<]
                vu.cntR = vl.cntR + vr.cntR;
            }

            // dbg(vl);
            // dbg(vr);
            // dbg(vu);
        }
    }

    inline void pushup(int u){
        merge_node(tree[u], tree[lu], tree[ru]);
    }

    inline void node_flip(int u){
        swap(tree[u].val[0], tree[u].val[1]);
        tree[u].flip ^= 1;
    }

    inline void pushdown(int u){
        if (tree[u].flip){
            node_flip(lu);
            node_flip(ru);
            tree[u].flip = 0;
        }
    }

    void update(int u, int x, int y){
        // add num for interval [x,y)
        if (tree[u].l >= y || tree[u].r <= x) return;
        if (tree[u].l >= x && tree[u].r <= y){
            node_flip(u);
            return;
        }
        pushdown(u);
        update(lu, x, y);
        update(ru, x, y);
        pushup(u);
    }

    inline node getmax(int u, int x, int y){
        if (tree[u].l >= y || tree[u].r <= x){
            //empty node
            node emp;
            emp.l = 1, emp.r = 0;
            return emp;
        }
        if (tree[u].l >= x && tree[u].r <= y) return tree[u];
        pushdown(u);
        node ret;
        merge_node(ret, getmax(lu, x, y), getmax(ru, x, y));
        return ret;
    }

    void build(int u, int x, int y, vi &a){
        tree[u].l = x;
        tree[u].r = y;
        tree[u].flip = 0;

        rep(i,2){
            info &vu = tree[u].val[i];
            vu.max = 1;
            vu.cntL = vu.cntR = 1;
            vu.dirL = vu.dirR = a[x] ^ i;
        }

        if (x + 1 == y) return;
        build(lu, x, (x+y)/2, a);
        build(ru, (x+y)/2, y, a);
        pushup(u);

        dbg(u, tree[u].l, tree[u].r, tree[u].flip);
        dbg(tree[u].val[0]);
        dbg(tree[u].val[1]);
    }

    void init(int _n, vi &a){
        dbg(a);
        n = _n;
        build(1, 0, n, a);
    }

    void display(){
        std::cerr << "SGT: ";
        rep(i,n) std::cerr << getmax(1, i, i + 1).val[0].max << " ";
        std::cerr << endl;
    }
}
void pre(){
}

void solve(){
    int n,m;
    cin >> n >> m;
    string s;
    cin >> s;
    vi a(n);
    rep(i,n) a[i] = (s[i] == '>');
    SGT::init(n, a);
    // cout << SGT::tree[1].val[0].max <<endl;
    while(m--){
        int l, r;
        cin >> l >> r;
        l--;
        SGT::update(1, l, r);
        SGT::node ret = SGT::getmax(1, l, r);
        cout << ret.val[0].max << endl;
    }
}

int main() {
    sync;
    int cas = 1;
    // cin >> cas;
    pre();
    rep(ca, cas) solve();
    return 0;
}


//pragma
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

#define YOU using
#define DONT namespace
#define SAY std

YOU DONT SAY;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ll,int> pli;
typedef pair<int,ll> pil;
typedef vector<int> vi;
typedef vector<pii> vii;
typedef vector<pll> vll;

#define REPP(i,a,b,d) for(int i=a;i<=b;i+=d)
#define REP(i,a,b) REPP(i,a,b,1)
#define REVV(i,a,b,d) for(int i=a;i>=b;i-=d)
#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) for(int i=0; i<a; i++)
#define FORD(i,a) for(int i=(int)a-1; i>=0; i--)

#define pb push_back
#define F first
#define S second

const int OO = 1e9;
const ll INF = 1e18;

const int irand(int lo,int hi){
	return ((double)rand()/(RAND_MAX + 1.0)) * (hi-lo+1) + lo;
}

const ll lrand(ll lo,ll hi){
	return ((double)rand()/(RAND_MAX + 1.0)) * (hi-lo+1) + lo;
}

#define getc getchar
template<typename T>
T getnum(){
	int sign = 1;
	T ret = 0;
	char c;

	do{
		c = getc();
	}while(c == ' ' || c == '\n');
	if(c == '-')sign = -1;
	else ret = c-'0';
	while(1){
		c = getc();
		if(c < '0' || c > '9')break;
		ret = 10*ret + c-'0';
	}
	return sign * ret;
}

inline void ini(int& x){
	x = getnum<int>();
}

inline void scani(int& x){
	scanf("%d",&x);
}

//end of macro

const int N = 5e5 + 5;

int n,q;
string str;

struct node{
    int v0, v1; // 0 real, 1 when flipped
    bool fl, fr;
    vi vec;
}tree[4*N], nnull;
bool pend[4*N];

int vback(vi v){
    if(v.size() == 1)return v[0];
    return v[v.size()-1] + v[v.size()-2];
}
int vfront(vi v){
    if(v.size() == 1)return v[0];
    return v[0] + v[1];
}

inline void reduce(vi& v){
    if(v.size() <= 4)return;
    int b = v.back(); v.pop_back();
    int a = v.back(); v.pop_back();
    while(v.size() > 2)v.pop_back();
    v.pb(a); v.pb(b);
}

inline char cat(int x, bool flip){
    char ret = str[x];
    if(flip){
        if(ret == '<')ret = '>';
        else ret = '<';
    }
    return ret;
}

node combine(node a, node b, int mid){
    if(a.v0 == -1)return b;
    if(b.v0 == -1)return a;

    node ret;
    ret.v0 = max(a.v0, b.v0);
    ret.v1 = max(a.v1, b.v1);
    ret.fl = a.fl;
    ret.fr = b.fr;

    bool pa = a.fr, pb = b.fl;

    if(cat(mid, pa) == '<' && cat(mid+1, pb) == '<'){
        ret.v0 = max(ret.v0, vback(a.vec) + b.vec[0]);
        ret.v1 = max(ret.v1, a.vec.back() + vfront(b.vec));
    }else if(cat(mid, pa) == '>' && cat(mid+1, pb) == '>'){
        ret.v1 = max(ret.v1, vback(a.vec) + b.vec[0]);
        ret.v0 = max(ret.v0, a.vec.back() + vfront(b.vec));
    }else if(cat(mid, pa) == '>' && cat(mid+1, pb) == '<'){
        ret.v0 = max(ret.v0, a.vec.back() + b.vec[0]);
    }else if(cat(mid, pa) == '<' && cat(mid+1, pb) == '>'){
        ret.v1 = max(ret.v1, a.vec.back() + b.vec[0]);
    }

    ret.vec = a.vec;
    if(cat(mid, pa) == cat(mid+1, pb)){
        ret.vec.back() += b.vec[0];
    }else{
        ret.vec.pb(b.vec[0]);
    }
    for(int i=1; i<b.vec.size(); i++){
        ret.vec.pb(b.vec[i]);
    }

    reduce(ret.vec);

    return ret;
}

void build(int idx, int left, int right){
    if(left == right){
        tree[idx].v0 = 1;
        tree[idx].v1 = 1;
        tree[idx].fl = tree[idx].fr = 0;
        tree[idx].vec.pb(1);
    }else{
        int mid = (left+right)/2;
        build(idx<<1, left, mid);
        build(idx<<1|1, mid+1, right);
        tree[idx] = combine(tree[idx<<1], tree[idx<<1|1], mid);
    }
}

void apply(int idx){
    swap(tree[idx].v0, tree[idx].v1);
    tree[idx].fl ^= 1;
    tree[idx].fr ^= 1;
    pend[idx] ^= 1;
}

void prop(int idx){
    if(pend[idx]){
        apply(idx<<1);
        apply(idx<<1|1);
        pend[idx] = 0;
    }
}

void uflip(int idx, int left, int right, int l, int r){
    if(left >= l && right <= r){
        apply(idx);
    }else if(right < l || left > r){
        // do nothing
    }else{
        int mid = (left+right)/2;
        uflip(idx<<1, left, mid, l, r);
        uflip(idx<<1|1, mid+1, right, l, r);
        tree[idx] = combine(tree[idx<<1], tree[idx<<1|1], mid);
    }
}

node query(int idx, int left, int right, int l, int r){
    if(left >= l && right <= r){
        return tree[idx];
    }else if(right < l || left > r){
        return nnull;
    }else{
        int mid = (left+right)/2;
        node nl = query(idx<<1, left, mid, l, r);
        node nr = query(idx<<1|1, mid+1, right, l, r);
        return combine(nl, nr, mid);
    }
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #define endl '\n'
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(10);

    nnull.v0 = -1;

    cin>>n>>q;
    cin>>str;

    build(1, 0, n-1);

    while(q--){
        int l, r;
        cin>>l>>r;
        l--, r--;
        uflip(1, 0, n-1, l, r);
        node res = query(1, 0, n-1, l, r);
        cout << res.v0 << endl;
        // printf("query %d %d\n",res.v0, res.v1);
        // for(auto x : res.vec)printf("%d ",x);printf("\n");
        // printf("%c %c\n",cat(l, res.fl), cat(r, res.fr));
    }

    return 0;
}


//pragma
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

#define YOU using
#define DONT namespace
#define SAY std

YOU DONT SAY;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ll,int> pli;
typedef pair<int,ll> pil;
typedef vector<int> vi;
typedef vector<pii> vii;
typedef vector<pll> vll;

#define REPP(i,a,b,d) for(int i=a;i<=b;i+=d)
#define REP(i,a,b) REPP(i,a,b,1)
#define REVV(i,a,b,d) for(int i=a;i>=b;i-=d)
#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) for(int i=0; i<a; i++)
#define FORD(i,a) for(int i=(int)a-1; i>=0; i--)

#define pb push_back
#define F first
#define S second

const int OO = 1e9;
const ll INF = 1e18;

const int irand(int lo,int hi){
	return ((double)rand()/(RAND_MAX + 1.0)) * (hi-lo+1) + lo;
}

const ll lrand(ll lo,ll hi){
	return ((double)rand()/(RAND_MAX + 1.0)) * (hi-lo+1) + lo;
}

#define getc getchar
template<typename T>
T getnum(){
	int sign = 1;
	T ret = 0;
	char c;

	do{
		c = getc();
	}while(c == ' ' || c == '\n');
	if(c == '-')sign = -1;
	else ret = c-'0';
	while(1){
		c = getc();
		if(c < '0' || c > '9')break;
		ret = 10*ret + c-'0';
	}
	return sign * ret;
}

inline void ini(int& x){
	x = getnum<int>();
}

inline void scani(int& x){
	scanf("%d",&x);
}

//end of macro

const int N = 5e5 + 5;

int n,q;
string str;

struct node{
    int v0, v1; // 0 real, 1 when flipped
    bool fl, fr;
    vi vec;
}tree[4*N], nnull;
bool pend[4*N];

inline int vback(const vi& v){
    if(v.size() == 1)return v[0];
    return v[v.size()-1] + v[v.size()-2];
}
inline int vfront(const vi& v){
    if(v.size() == 1)return v[0];
    return v[0] + v[1];
}

inline void reduce(vi& v){
    if(v.size() <= 4)return;
    int b = v.back(); v.pop_back();
    int a = v.back(); v.pop_back();
    while(v.size() > 2)v.pop_back();
    v.pb(a); v.pb(b);
}

inline char cat(int x, bool flip){
    char ret = str[x];
    if(flip){
        if(ret == '<')ret = '>';
        else ret = '<';
    }
    return ret;
}

inline node combine(const node& a, const node& b, int mid){
    if(a.v0 == -1)return b;
    if(b.v0 == -1)return a;

    node ret;
    ret.v0 = max(a.v0, b.v0);
    ret.v1 = max(a.v1, b.v1);
    ret.fl = a.fl;
    ret.fr = b.fr;

    bool pa = a.fr, pb = b.fl;

    if(cat(mid, pa) == '<' && cat(mid+1, pb) == '<'){
        ret.v0 = max(ret.v0, vback(a.vec) + b.vec[0]);
        ret.v1 = max(ret.v1, a.vec.back() + vfront(b.vec));
    }else if(cat(mid, pa) == '>' && cat(mid+1, pb) == '>'){
        ret.v1 = max(ret.v1, vback(a.vec) + b.vec[0]);
        ret.v0 = max(ret.v0, a.vec.back() + vfront(b.vec));
    }else if(cat(mid, pa) == '>' && cat(mid+1, pb) == '<'){
        ret.v0 = max(ret.v0, a.vec.back() + b.vec[0]);
    }else if(cat(mid, pa) == '<' && cat(mid+1, pb) == '>'){
        ret.v1 = max(ret.v1, a.vec.back() + b.vec[0]);
    }

    ret.vec = a.vec;
    if(cat(mid, pa) == cat(mid+1, pb)){
        ret.vec.back() += b.vec[0];
    }else{
        ret.vec.pb(b.vec[0]);
    }
    for(int i=1; i<b.vec.size(); i++){
        ret.vec.pb(b.vec[i]);
    }

    reduce(ret.vec);

    return ret;
}

void build(int idx, int left, int right){
    if(left == right){
        tree[idx].v0 = 1;
        tree[idx].v1 = 1;
        tree[idx].fl = tree[idx].fr = 0;
        tree[idx].vec.pb(1);
    }else{
        int mid = (left+right)/2;
        build(idx<<1, left, mid);
        build(idx<<1|1, mid+1, right);
        tree[idx] = combine(tree[idx<<1], tree[idx<<1|1], mid);
    }
}

inline void apply(int idx){
    swap(tree[idx].v0, tree[idx].v1);
    tree[idx].fl ^= 1;
    tree[idx].fr ^= 1;
    pend[idx] ^= 1;
}

inline void prop(int idx){
    if(pend[idx]){
        apply(idx<<1);
        apply(idx<<1|1);
        pend[idx] = 0;
    }
}

void uflip(int idx, int left, int right, int l, int r){
    if(left >= l && right <= r){
        apply(idx);
    }else if(right < l || left > r){
        // do nothing
    }else{
        int mid = (left+right)/2;
        uflip(idx<<1, left, mid, l, r);
        uflip(idx<<1|1, mid+1, right, l, r);
        tree[idx] = combine(tree[idx<<1], tree[idx<<1|1], mid);
    }
}

node query(int idx, int left, int right, int l, int r){
    if(left >= l && right <= r){
        return tree[idx];
    }else if(right < l || left > r){
        return nnull;
    }else{
        int mid = (left+right)/2;
        const node& nl = query(idx<<1, left, mid, l, r);
        const node& nr = query(idx<<1|1, mid+1, right, l, r);
        return combine(nl, nr, mid);
    }
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #define endl '\n'
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(10);

    nnull.v0 = -1;

    cin>>n>>q;
    cin>>str;

    build(1, 0, n-1);

    while(q--){
        int l, r;
        cin>>l>>r;
        l--, r--;
        uflip(1, 0, n-1, l, r);
        node res = query(1, 0, n-1, l, r);
        cout << res.v0 << endl;
        // printf("query %d %d\n",res.v0, res.v1);
        // for(auto x : res.vec)printf("%d ",x);printf("\n");
        // printf("%c %c\n",cat(l, res.fl), cat(r, res.fr));
    }

    return 0;
}


//pragma
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>

#define YOU using
#define DONT namespace
#define SAY std

YOU DONT SAY;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ll,int> pli;
typedef pair<int,ll> pil;
typedef vector<int> vi;
typedef vector<pii> vii;
typedef vector<pll> vll;

#define REPP(i,a,b,d) for(int i=a;i<=b;i+=d)
#define REP(i,a,b) REPP(i,a,b,1)
#define REVV(i,a,b,d) for(int i=a;i>=b;i-=d)
#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,a) for(int i=0; i<a; i++)
#define FORD(i,a) for(int i=(int)a-1; i>=0; i--)

#define pb push_back
#define F first
#define S second

const int OO = 1e9;
const ll INF = 1e18;

const int irand(int lo,int hi){
	return ((double)rand()/(RAND_MAX + 1.0)) * (hi-lo+1) + lo;
}

const ll lrand(ll lo,ll hi){
	return ((double)rand()/(RAND_MAX + 1.0)) * (hi-lo+1) + lo;
}

#define getc getchar
template<typename T>
T getnum(){
	int sign = 1;
	T ret = 0;
	char c;

	do{
		c = getc();
	}while(c == ' ' || c == '\n');
	if(c == '-')sign = -1;
	else ret = c-'0';
	while(1){
		c = getc();
		if(c < '0' || c > '9')break;
		ret = 10*ret + c-'0';
	}
	return sign * ret;
}

inline void ini(int& x){
	x = getnum<int>();
}

inline void scani(int& x){
	scanf("%d",&x);
}

//end of macro

const int N = 5e5 + 5;

int n,q;
string str;

struct node{
    int v0, v1; // 0 real, 1 when flipped
    bool fl, fr;
    vi vec;
}tree[4*N], nnull;
bool pend[4*N];

inline int vback(const vi& v){
    if(v.size() == 1)return v[0];
    return v[v.size()-1] + v[v.size()-2];
}
inline int vfront(const vi& v){
    if(v.size() == 1)return v[0];
    return v[0] + v[1];
}

inline void reduce(vi& v){
    if(v.size() <= 4)return;
    int b = v.back(); v.pop_back();
    int a = v.back(); v.pop_back();
    while(v.size() > 2)v.pop_back();
    v.pb(a); v.pb(b);
}

inline char cat(int x, bool flip){
    char ret = str[x];
    if(flip){
        if(ret == '<')ret = '>';
        else ret = '<';
    }
    return ret;
}

inline node combine(const node& a, const node& b, int mid){
    if(a.v0 == -1)return b;
    if(b.v0 == -1)return a;

    node ret;
    ret.v0 = max(a.v0, b.v0);
    ret.v1 = max(a.v1, b.v1);
    ret.fl = a.fl;
    ret.fr = b.fr;

    bool pa = a.fr, pb = b.fl;

    if(cat(mid, pa) == '<' && cat(mid+1, pb) == '<'){
        ret.v0 = max(ret.v0, vback(a.vec) + b.vec[0]);
        ret.v1 = max(ret.v1, a.vec.back() + vfront(b.vec));
    }else if(cat(mid, pa) == '>' && cat(mid+1, pb) == '>'){
        ret.v1 = max(ret.v1, vback(a.vec) + b.vec[0]);
        ret.v0 = max(ret.v0, a.vec.back() + vfront(b.vec));
    }else if(cat(mid, pa) == '>' && cat(mid+1, pb) == '<'){
        ret.v0 = max(ret.v0, a.vec.back() + b.vec[0]);
    }else if(cat(mid, pa) == '<' && cat(mid+1, pb) == '>'){
        ret.v1 = max(ret.v1, a.vec.back() + b.vec[0]);
    }

    ret.vec = a.vec;
    if(cat(mid, pa) == cat(mid+1, pb)){
        ret.vec.back() += b.vec[0];
    }else{
        ret.vec.pb(b.vec[0]);
    }
    for(int i=1; i<b.vec.size(); i++){
        ret.vec.pb(b.vec[i]);
    }

    reduce(ret.vec);

    return ret;
}

void build(int idx, int left, int right){
    if(left == right){
        tree[idx].v0 = 1;
        tree[idx].v1 = 1;
        tree[idx].fl = tree[idx].fr = 0;
        tree[idx].vec.pb(1);
    }else{
        int mid = (left+right)/2;
        build(idx<<1, left, mid);
        build(idx<<1|1, mid+1, right);
        tree[idx] = combine(tree[idx<<1], tree[idx<<1|1], mid);
    }
}

inline void apply(int idx){
    swap(tree[idx].v0, tree[idx].v1);
    tree[idx].fl ^= 1;
    tree[idx].fr ^= 1;
    pend[idx] ^= 1;
}

inline void prop(int idx){
    if(pend[idx]){
        apply(idx<<1);
        apply(idx<<1|1);
        pend[idx] = 0;
    }
}

void uflip(int idx, int left, int right, int l, int r){
    if(left >= l && right <= r){
        apply(idx);
    }else if(right < l || left > r){
        // do nothing
    }else{
        prop(idx);
        int mid = (left+right)/2;
        uflip(idx<<1, left, mid, l, r);
        uflip(idx<<1|1, mid+1, right, l, r);
        tree[idx] = combine(tree[idx<<1], tree[idx<<1|1], mid);
    }
}

node query(int idx, int left, int right, int l, int r){
    if(left >= l && right <= r){
        return tree[idx];
    }else if(right < l || left > r){
        return nnull;
    }else{
        prop(idx);
        int mid = (left+right)/2;
        const node& nl = query(idx<<1, left, mid, l, r);
        const node& nr = query(idx<<1|1, mid+1, right, l, r);
        return combine(nl, nr, mid);
    }
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    #define endl '\n'
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(10);

    nnull.v0 = -1;
    nnull.v1 = -1;

    cin>>n>>q;
    cin>>str;

    build(1, 0, n-1);

    while(q--){
        int l, r;
        cin>>l>>r;
        l--, r--;
        uflip(1, 0, n-1, l, r);
        node res = query(1, 0, n-1, l, r);
        cout << res.v0 << endl;
        // printf("query %d %d\n",res.v0, res.v1);
        // for(auto x : res.vec)printf("%d ",x);printf("\n");
        // printf("%c %c\n",cat(l, res.fl), cat(r, res.fr));
    }

    return 0;
}