#include <bits/stdc++.h>
using namespace std;

class Seg {
  int l, m, r;
  long long al, am, ar;
  Seg* ch[2] = {0};
  bool flip = false;
  int tag = -1;
  int sum = 0;
  void push() {
    if (flip) {
      for (int i : {0, 1}) {
        if (ch[i]->tag != -1) {
          ch[i]->tag = !ch[i]->tag;
          ch[i]->sum = ch[i]->tag * ch[i]->size();
        }
        else {
          ch[i]->flip ^= 1;
          ch[i]->sum = ch[i]->size() - ch[i]->sum;
        }
      }
      flip = false;
    }
    else if (tag != -1) {
      for (int i : {0, 1}) {
        ch[i]->tag = tag;
        ch[i]->flip = false;
        ch[i]->sum = ch[i]->size() * tag;
      }
      tag = -1;
    }
  }
  void pull() { sum = ch[0]->sum + ch[1]->sum; }
public:
  int size() { return r - l; }
  Seg(int l, int r, const vector<long long> &X) : l(l), r(r), m(l + r >> 1) {
    al = X[l], ar = X[r];
    if (r - l > 1) {
      am = X[m];
      ch[0] = new Seg(l, m, X);
      ch[1] = new Seg(m, r, X);
      pull();
    }
  }
  void apply(int ql, int qr, int v) {
    if (ql <= l and r <= qr) {
      tag = v, sum = v * size();
    }
    else {
      push();
      if (ql < m) ch[0]->apply(ql, qr, v);
      if (m < qr) ch[1]->apply(ql, qr, v);
      pull();
    }
  }
  void reverse(int ql, int qr) {
    if (ql <= l and r <= qr) {
      if (tag != -1) tag = !tag, sum = tag * size();
      else flip = !flip, sum = size() - sum;
    }
    else {
      push();
      if (ql < m) ch[0]->reverse(ql, qr);
      if (m < qr) ch[1]->reverse(ql, qr);
      pull();
    }
  }
  long long mex() {
    if (sum == 0) return al;
    push();
    return ch[ch[0]->size() == ch[0]->sum]->mex();
  }
};

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);
  int n; cin >> n;
  vector<tuple<int, long long, long long>> qs;
  vector<long long> X; map<long long, int> mp;
  set<long long> __ = {1ll, 1ll << 60};
  for (int i = 0; i < n; ++i) {
    long long t, l, r; cin >> t >> l >> r;
    qs.emplace_back(t, l, r + 1);
    __.insert(l);
    __.insert(r + 1);
  }
  for (auto c : __) {
    int sz = mp.size();
    X.push_back(c);
    mp[c] = sz;
  }

  Seg root(0, X.size() - 1, X);

  for (int i = 0; i < n; ++i) {
    auto [t, l, r] = qs[i];
    if (t == 3) root.reverse(mp[l], mp[r]);
    else root.apply(mp[l], mp[r], 2 - t);
    cout << root.mex() << '\n';
  }
}


#include <bits/stdc++.h>
using namespace std;

class Seg {
  int l, m, r;
  long long al, ar;
  Seg* ch[2] = {0};
  bool flip = false;
  int tag = -1;
  int sum = 0;
  void push() {
    if (flip) {
      for (int i : {0, 1}) {
        if (ch[i]->tag != -1) {
          ch[i]->tag = !ch[i]->tag;
          ch[i]->sum = ch[i]->tag * ch[i]->size();
        }
        else {
          ch[i]->flip ^= 1;
          ch[i]->sum = ch[i]->size() - ch[i]->sum;
        }
      }
      flip = false;
    }
    else if (tag != -1) {
      for (int i : {0, 1}) {
        ch[i]->tag = tag;
        ch[i]->flip = false;
        ch[i]->sum = ch[i]->size() * tag;
      }
      tag = -1;
    }
  }
  void pull() { sum = ch[0]->sum + ch[1]->sum; }
public:
  int size() { return r - l; }
  Seg(int l, int r, const vector<long long> &X) : l(l), r(r), m(l + r >> 1) {
    al = X[l], ar = X[r];
    if (r - l > 1) {
      ch[0] = new Seg(l, m, X);
      ch[1] = new Seg(m, r, X);
      pull();
    }
  }
  void apply(int ql, int qr, int v) {
    if (ql <= l and r <= qr) {
      tag = v, sum = v * size();
    }
    else {
      push();
      if (ql < m) ch[0]->apply(ql, qr, v);
      if (m < qr) ch[1]->apply(ql, qr, v);
      pull();
    }
  }
  void reverse(int ql, int qr) {
    if (ql <= l and r <= qr) {
      if (tag != -1) tag = !tag, sum = tag * size();
      else flip = !flip, sum = size() - sum;
    }
    else {
      push();
      if (ql < m) ch[0]->reverse(ql, qr);
      if (m < qr) ch[1]->reverse(ql, qr);
      pull();
    }
  }
  long long mex() {
    if (sum == 0) return al;
    assert(r - l > 1);
    push();
    return ch[ch[0]->size() == ch[0]->sum]->mex();
  }
};

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);
  int n; cin >> n;
  vector<tuple<int, long long, long long>> qs;
  vector<long long> X; map<long long, int> mp;
  set<long long> __ = {1ll, 1ll << 60};
  for (int i = 0; i < n; ++i) {
    long long t, l, r; cin >> t >> l >> r;
    qs.emplace_back(t, l, r + 1);
    __.insert(l);
    __.insert(r + 1);
  }
  for (auto c : __) {
    int sz = mp.size();
    X.push_back(c);
    mp[c] = sz;
  }

  Seg root(0, X.size() - 1, X);

  for (int i = 0; i < n; ++i) {
    auto [t, l, r] = qs[i];
    if (t == 3) root.reverse(mp[l], mp[r]);
    else root.apply(mp[l], mp[r], 2 - t);
    cout << root.mex() << '\n';
  }
}


#include <bits/stdc++.h>
using namespace std;

class Seg {
  long long l, m, r;
  Seg* ch[2] = {0};
  bool flip = false;
  int tag = -1;
  long long sum = 0;
  void push() {
    if (not ch[0]) ch[0] = new Seg(l, m);
    if (not ch[1]) ch[1] = new Seg(m, r);
    if (flip) {
      for (int i : {0, 1}) {
        if (ch[i]->tag != -1) {
          ch[i]->tag = !ch[i]->tag;
          ch[i]->sum = ch[i]->tag * ch[i]->size();
        }
        else {
          ch[i]->flip ^= 1;
          ch[i]->sum = ch[i]->size() - ch[i]->sum;
        }
      }
      flip = false;
    }
    else if (tag != -1) {
      for (int i : {0, 1}) {
        ch[i]->tag = tag;
        ch[i]->flip = false;
        ch[i]->sum = ch[i]->size() * tag;
      }
      tag = -1;
    }
  }
  void pull() { sum = ch[0]->sum + ch[1]->sum; }
public:
  long long size() { return r - l; }
  Seg(long long l, long long r) : l(l), r(r), m((l + r) / 2) {}
  void apply(long long ql, long long qr, int v) {
    if (ql <= l and r <= qr) {
      tag = v, sum = v * size();
    }
    else {
      push();
      if (ql < m) ch[0]->apply(ql, qr, v);
      if (m < qr) ch[1]->apply(ql, qr, v);
      pull();
    }
  }
  void reverse(long long ql, long long qr) {
    if (ql <= l and r <= qr) {
      if (tag != -1) tag = !tag, sum = tag * size();
      else flip = !flip, sum = size() - sum;
    }
    else {
      push();
      if (ql < m) ch[0]->reverse(ql, qr);
      if (m < qr) ch[1]->reverse(ql, qr);
      pull();
    }
  }
  long long mex() {
    if (sum == 0) return l;
    push();
    return ch[ch[0]->size() == ch[0]->sum]->mex();
  }
};

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);
  Seg root(0ll, 1ll<<60);
  root.apply(0, 1, 1);
  int n; cin >> n;
  while (n--) {
    long long t, l, r; cin >> t >> l >> r;
    ++r;
    if (t == 3) root.reverse(l, r);
    else root.apply(l, r, 2 - t);
    cout << root.mex() << '\n';
  }
}


#include <bits/stdc++.h>
using namespace std;

class Seg {
  int l, m, r;
  long long al;
  Seg* ch[2] = {0};
  bool flip = false;
  int tag = -1;
  int sum = 0;
  void push() {
    if (flip) {
      for (int i : {0, 1}) {
        if (ch[i]->tag != -1) {
          ch[i]->tag = !ch[i]->tag;
          ch[i]->sum = ch[i]->tag * ch[i]->size();
        }
        else {
          ch[i]->flip ^= 1;
          ch[i]->sum = ch[i]->size() - ch[i]->sum;
        }
      }
      flip = false;
    }
    else if (tag != -1) {
      for (int i : {0, 1}) {
        ch[i]->tag = tag;
        ch[i]->flip = false;
        ch[i]->sum = ch[i]->size() * tag;
      }
      tag = -1;
    }
  }
  void pull() { sum = ch[0]->sum + ch[1]->sum; }
public:
  int size() { return r - l; }
  Seg(int l, int r, const vector<long long> &X) : l(l), r(r), m(l + r >> 1) {
    al = X[l];
    if (r - l > 1) {
      ch[0] = new Seg(l, m, X);
      ch[1] = new Seg(m, r, X);
      pull();
    }
  }
  void apply(int ql, int qr, int v) {
    if (ql <= l and r <= qr) {
      tag = v, sum = v * size(), flip = false;
    }
    else {
      push();
      if (ql < m) ch[0]->apply(ql, qr, v);
      if (m < qr) ch[1]->apply(ql, qr, v);
      pull();
    }
  }
  void reverse(int ql, int qr) {
    if (ql <= l and r <= qr) {
      if (tag != -1) tag = !tag, sum = tag * size();
      else flip = !flip, sum = size() - sum;
    }
    else {
      push();
      if (ql < m) ch[0]->reverse(ql, qr);
      if (m < qr) ch[1]->reverse(ql, qr);
      pull();
    }
  }
  long long mex() {
    if (sum == 0) return al;
    push();
    return ch[ch[0]->size() == ch[0]->sum]->mex();
  }
};

int main() {
  ios_base::sync_with_stdio(false); cin.tie(0);
  int n; cin >> n;
  vector<tuple<int, long long, long long>> qs;
  vector<long long> X; map<long long, int> mp;
  set<long long> __ = {1ll, 1ll << 60};
  for (int i = 0; i < n; ++i) {
    long long t, l, r; cin >> t >> l >> r;
    ++r;
    qs.emplace_back(t, l, r);
    __.insert(l);
    __.insert(r);
  }
  for (auto c : __) {
    int sz = mp.size();
    X.push_back(c);
    mp[c] = sz;
  }

  Seg root(0, X.size() - 1, X);

  for (int i = 0; i < n; ++i) {
    auto [t, l, r] = qs[i];
    if (t == 3) root.reverse(mp[l], mp[r]);
    else root.apply(mp[l], mp[r], 2 - t);
    cout << root.mex() << '\n';
  }
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
	char ch = getchar(); int x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e5 + 10;
ll tree[N<<2];
ll lazy[N<<2];
ll lazy2[N];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[lrt] = lazy[rrt] = lazy[root];
		lazy2[lrt] = lazy2[rrt] = 0;
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[lrt] += lazy2[root];
		lazy2[rrt] += lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { int l, r, op; }a[N];
int t, l, r, n;
int findpos(int val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int l = 0; int r = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (r - 1 > l)
		{
			int midd = (r + l) >> 1;
		//	cout << "midd" << midd << endl;
			int temp = querry(1, n, 1, 1, midd);
			//	cout << "temp" << temp << endl;
			if (temp == midd)l = midd;
			else r = midd;
		}
		printf("%lld\n", hi[r - 1]);
	}
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
	char ch = getchar(); int x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
ll tree[N];
ll lazy[N];
ll lazy2[N];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[lrt] = lazy[rrt] = lazy[root];
		lazy2[lrt] = lazy2[rrt] = 0;
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[lrt] += lazy2[root];
		lazy2[rrt] += lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { int l, r, op; }a[N];
int t, l, r, n;
int findpos(int val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int l = 0; int r = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (r - 1 > l)
		{
			int midd = (r + l) >> 1;
		//	cout << "midd" << midd << endl;
			int temp = querry(1, n, 1, 1, midd);
			//	cout << "temp" << temp << endl;
			if (temp == midd)l = midd;
			else r = midd;
		}
		printf("%lld\n", hi[r - 1]);
	}
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
	char ch = getchar(); int x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
ll tree[N];
ll lazy[N];
ll lazy2[N];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[lrt] = lazy[rrt] = lazy[root];
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[lrt] += lazy2[root];
		lazy2[rrt] += lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { int l, r, op; }a[N];
int t, l, r, n;
int findpos(int val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int limlf = 0; int limrt = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (limrt - 1 > limlf)
		{
			int midd = (limrt + limlf) >> 1;
		//	cout << "midd" << midd << endl;
			int temp = querry(1, n, 1, 1, midd);
			//	cout << "temp" << temp << endl;
			if (temp == midd)limlf = midd;
			else limrt = midd;
		}
		printf("%lld\n", hi[limrt - 1]);
	}
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
	char ch = getchar(); int x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e5 + 10;
ll tree[N<<2];
ll lazy[N<<2];
ll lazy2[N<<2];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[lrt] = lazy[rrt] = lazy[root];
		lazy2[lrt] = lazy2[rrt] = 0;
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[lrt] += lazy2[root];
		lazy2[rrt] += lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { int l, r, op; }a[N];
int t, l, r, n;
int findpos(int val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int l = 0; int r = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (r - 1 > l)
		{
			int midd = (r + l) >> 1;
		//	cout << "midd" << midd << endl;
			int temp = querry(1, n, 1, 1, midd);
			//	cout << "temp" << temp << endl;
			if (temp == midd)l = midd;
			else r = midd;
		}
		printf("%lld\n", hi[r - 1]);
	}
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 4e5 + 10;
ll tree[N<<2];
ll lazy[N<<2];
ll lazy2[N<<2];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[lrt] = lazy[rrt] = lazy[root];
		lazy2[lrt] = lazy2[rrt] = 0;
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[lrt] += lazy2[root];
		lazy2[rrt] += lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy2[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { ll l, r, op; }a[N];
ll t, l, r, n;
int findpos(ll val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int l = 0; int r = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (r - 1 > l)
		{
			int midd = (r + l) >> 1;
			//cout << "midd" << midd << endl;
			int temp = querry(1, n, 1, 1, midd);
				//cout << "temp" << temp << endl;
			if (temp == midd)l = midd;
			else r = midd;
		}
		printf("%lld\n", hi[r - 1]);
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e5 + 10;
ll tree[N<<2];
ll lazy[N<<2];
ll lazy2[N<<2];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[lrt] = lazy[rrt] = lazy[root];
		lazy2[lrt] = lazy2[rrt] = 0;
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[lrt] += lazy2[root];
		lazy2[rrt] += lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { ll l, r, op; }a[N];
ll t, l, r, n;
int findpos(ll val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int l = 0; int r = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (r - 1 > l)
		{
			int midd = (r + l) >> 1;
			//cout << "midd" << midd << endl;
			int temp = querry(1, n, 1, 1, midd);
				//cout << "temp" << temp << endl;
			if (temp == midd)l = midd;
			else r = midd;
		}
		printf("%lld\n", hi[r - 1]);
	}
	return 0;
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
	char ch = getchar(); ll x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 2e5 + 10;
ll tree[N<<2];
ll lazy[N<<2];
ll lazy2[N<<2];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[lrt] = lazy[rrt] = lazy[root];
		lazy2[lrt] = lazy2[rrt] = 0;
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[lrt] += lazy2[root];
		lazy2[rrt] += lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { ll l, r, op; }a[N];
ll t, l, r, n;
int findpos(int val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int l = 0; int r = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (r - 1 > l)
		{
			int midd = (r + l) >> 1;
		//	cout << "midd" << midd << endl;
			int temp = querry(1, n, 1, 1, midd);
			//	cout << "temp" << temp << endl;
			if (temp == midd)l = midd;
			else r = midd;
		}
		printf("%lld\n", hi[r - 1]);
	}
}


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b)  for(int i=a;i<b;i++)
#define dw(i,a,b)  for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
int read()
{
	char ch = getchar(); int x = 0, f = 1;
	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
typedef pair<int, int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const int N = 1e5 + 10;
ll tree[N];
ll lazy[N];
ll lazy2[N];
void pushup(int root)
{
	tree[root] = tree[lrt] + tree[rrt];
}
void pushdown(int root,int l,int r)
{
	int lenr = (r - l + 1) >> 1;
	int lenl = (r - l + 1) - lenr;
	if (lazy[root])
	{
		lazy[root<<1] = lazy[rrt] = lazy[root];
		if (lazy[root] == 1)
		{
			tree[lrt] = lenl, tree[rrt] = lenr;
		}
		else if (lazy[root] == 2)
		{
			tree[lrt] = tree[rrt] = 0;
		}
		lazy[root] = 0;
	}
	if (lazy2[root] % 2)
	{
		lazy2[root << 1] +=  lazy2[root];
		lazy2[rrt] = lazy2[root];
		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
		lazy2[root] = 0;
	}
}
void build(int l, int r, int root)
{
	lazy[root] = 0; lazy[root] = 0;
	if (l == r)
	{
		tree[root] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(lson);
	build(rson);
	pushup(root);
}
void update(int l, int r, int root, int lf, int rt, int op)
{
	if (lf <= l && r <= rt)
	{
		if (op == 1)
		{
			tree[root] = r-l+1; lazy[root] = 1;
		}
		else if(op==2)
		{
			tree[root] = 0; lazy[root] = 2;
		}
		else
		{
			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
		}
		return;
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	if (lf <= mid)
	{
		update(lson, lf, rt, op);
	}
	if(rt>mid) update(rson, lf, rt, op);
	pushup(root);
}
int querry(int l, int r, int root,int lf,int rt)
{
	if (lf <= l && r <= rt)
	{
		return tree[root];
	}
	pushdown(root, l, r);
	int mid = (l + r) >> 1;
	int ans = 0;
	if (lf <= mid)ans += querry(lson, lf, rt);
	if (rt > mid)ans += querry(rson, lf, rt);
	return ans;
}
vector<ll>hi;
struct node { int l, r, op; }a[N];
int t, l, r, n;
int findpos(int val)
{
	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
}
int main()
{
	n = read();
	int lim = n;
	up(i, 0, n)
	{
		t = read(), l = read(), r = read();
		a[i] = node{ l,r,t };
		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
	}
	hi.push_back(1);
	sort(hi.begin(), hi.end());
	hi.erase(unique(hi.begin(), hi.end()), hi.end());
	n = hi.size();
	build(1, n, 1);
	up(i, 0,lim)
	{
		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
		update(1, n, 1, l, r, t);
		int limlf = 0; int limrt = n+1;
		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
		cout << "q" << querry(1, n, 1, 1, 4) << endl;
		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
		while (limrt - 1 > limlf)
		{
			int midd = (limrt + limlf) >> 1;
			int temp = querry(1, n, 1, 1, midd);
			//	cout << "temp" << temp << endl;
			if (temp == midd)limlf = midd;
			else limrt = midd;
		}
		printf("%lld\n", hi[limrt - 1]);
	}
}


    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<cstdlib>
    #include<climits>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<set>
    #include<map>
    //#include<regex>
    #include<cstdio>
    #define up(i,a,b)  for(int i=a;i<b;i++)
    #define dw(i,a,b)  for(int i=a;i>b;i--)
    #define upd(i,a,b) for(int i=a;i<=b;i++)
    #define dwd(i,a,b) for(int i=a;i>=b;i--)
    //#define local
    typedef long long ll;
    const double esp = 1e-6;
    const double pi = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const int inf = 1e9;
    using namespace std;
    ll read()
    {
    	char ch = getchar(); ll x = 0, f = 1;
    	while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
    	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    	return x * f;
    }
    typedef pair<int, int> pir;
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define lrt root<<1
    #define rrt root<<1|1
    const int N = 2e5 + 10;
    ll tree[N<<2];
    ll lazy[N<<2];
    ll lazy2[N<<2];
    void pushup(int root)
    {
    	tree[root] = tree[lrt] + tree[rrt];
    }
    void pushdown(int root,int l,int r)
    {
    	int lenr = (r - l + 1) >> 1;
    	int lenl = (r - l + 1) - lenr;
    	if (lazy[root])
    	{
    		lazy[lrt] = lazy[rrt] = lazy[root];
    		lazy2[lrt] = lazy2[rrt] = 0;
    		if (lazy[root] == 1)
    		{
    			tree[lrt] = lenl, tree[rrt] = lenr;
    		}
    		else if (lazy[root] == 2)
    		{
    			tree[lrt] = tree[rrt] = 0;
    		}
    		lazy[root] = 0;
    	}
    	if (lazy2[root] % 2)
    	{
    		lazy2[lrt] += lazy2[root];
    		lazy2[rrt] += lazy2[root];
    		tree[lrt] = lenl - tree[lrt]; tree[rrt] = lenr - tree[rrt];
    		lazy2[root] = 0;
    	}
    }
    void build(int l, int r, int root)
    {
    	lazy[root] = 0; lazy[root] = 0;
    	if (l == r)
    	{
    		tree[root] = 0;
    		return;
    	}
    	int mid = (l + r) >> 1;
    	build(lson);
    	build(rson);
    	pushup(root);
    }
    void update(int l, int r, int root, int lf, int rt, int op)
    {
    	if (lf <= l && r <= rt)
    	{
    		if (op == 1)
    		{
    			tree[root] = r - l + 1; lazy[root] = 1; lazy2[root] = 0;
    		}
    		else if(op==2)
    		{
    			tree[root] = 0; lazy[root] = 2; lazy2[root] = 0;
    		}
    		else
    		{
    			tree[root] = r - l + 1 - tree[root]; lazy2[root]++;
    		}
    		return;
    	}
    	pushdown(root, l, r);
    	int mid = (l + r) >> 1;
    	if (lf <= mid)
    	{
    		update(lson, lf, rt, op);
    	}
    	if(rt>mid) update(rson, lf, rt, op);
    	pushup(root);
    }
    int querry(int l, int r, int root,int lf,int rt)
    {
    	if (lf <= l && r <= rt)
    	{
    		return tree[root];
    	}
    	pushdown(root, l, r);
    	int mid = (l + r) >> 1;
    	int ans = 0;
    	if (lf <= mid)ans += querry(lson, lf, rt);
    	if (rt > mid)ans += querry(rson, lf, rt);
    	return ans;
    }
    vector<ll>hi;
    struct node { int l, r, op; }a[N];
    int t, l, r, n;
    int findpos(int val)
    {
    	return lower_bound(hi.begin(), hi.end(), val) - hi.begin();
    }
    int main()
    {
    	n = read();
    	int lim = n;
    	up(i, 0, n)
    	{
    		t = read(), l = read(), r = read();
    		a[i] = node{ l,r,t };
    		hi.push_back(l), hi.push_back(r); hi.push_back(r + 1); hi.push_back(l + 1);
    	}
    	hi.push_back(1);
    	sort(hi.begin(), hi.end());
    	hi.erase(unique(hi.begin(), hi.end()), hi.end());
    	n = hi.size();
    	build(1, n, 1);
    	up(i, 0,lim)
    	{
    		t = a[i].op; l = findpos(a[i].l)+1; r = findpos(a[i].r)+1;
    		update(1, n, 1, l, r, t);
    		int l = 0; int r = n+1;
    		/*cout << "q" << querry(1, n, 1, 1, n) << endl;
    		cout << "q" << querry(1, n, 1, 1, 4) << endl;
    		cout << "q" << querry(1, n, 1, 1, 2) << endl;*/
    	//	cout << "q" << querry(1, n, 1, 1, 1) << endl;
    		while (r - 1 > l)
    		{
    			int midd = (r + l) >> 1;
    		//	cout << "midd" << midd << endl;
    			int temp = querry(1, n, 1, 1, midd);
    			//	cout << "temp" << temp << endl;
    			if (temp == midd)l = midd;
    			else r = midd;
    		}
    		printf("%lld\n", hi[r - 1]);
    	}
    }


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;
const int maxn=1e5;
int F[maxn*6*4],G[maxn*6*4],lz1[maxn*6*4],lz2[maxn*6*4];
const int inf=1e9;
void pushdown(int rt,int l,int r,int v){
  lz2[rt]=v;
  if(v==-1)F[rt]=l,G[rt]=inf;
  else if(v==1)F[rt]=inf,G[rt]=l;
}
void upd(int rt,int l,int r,int ll,int rr,int v){
  int mid=(l+r)>>1;
  if(lz2[rt]){
    pushdown(rt<<1,l,mid,lz2[rt]);
    pushdown(rt<<1|1,mid+1,r,lz2[rt]);
    lz2[rt]=0;
  }
  if(ll<=l&&rr>=r){
    pushdown(rt,l,r,v);
    return;
  }
  if(ll<=mid)upd(rt<<1,l,mid,ll,rr,v);
  if(rr>mid)upd(rt<<1|1,mid+1,r,ll,rr,v);
  F[rt]=min(F[rt<<1],F[rt<<1|1]);
  G[rt]=min(G[rt<<1],G[rt<<1|1]);
}
void upd2(int rt,int l,int r,int ll,int rr){
  int mid=(l+r)>>1;
  if(lz2[rt]){
    pushdown(rt<<1,l,mid,lz2[rt]);
    pushdown(rt<<1|1,mid+1,r,lz2[rt]);
    lz2[rt]=0;
  }
  if(ll<=l&&rr>=r){
    lz1[rt]^=1;
    if(lz1[rt])swap(F[rt],G[rt]);
    return;
  }
  if(ll<=mid)upd2(rt<<1,l,mid,ll,rr);
  if(rr>mid)upd2(rt<<1|1,mid+1,r,ll,rr);
  F[rt]=min(F[rt<<1],F[rt<<1|1]);
  G[rt]=min(G[rt<<1],G[rt<<1|1]);
}
int t[maxn],l[maxn],r[maxn];
int main(){
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false),cout.tie(0),cin.tie(0);
  int n;
  cin>>n;
  vector<int> compress;
  for(int i=0;i<n;++i){
    cin>>t[i]>>l[i]>>r[i];
    compress.push_back(l[i]+1);
    compress.push_back(r[i]+1);
    compress.push_back(l[i]);
    compress.push_back(r[i]);
    compress.push_back(l[i]-1);
    compress.push_back(r[i]-1);
  }
  compress.push_back(0);
  sort(compress.begin(),compress.end());
  compress.erase(unique(compress.begin(),compress.end()),compress.end());
  int m=SZ(compress);
  upd(1,1,m,1,m,-1);
  for(int i=0;i<n;++i){
    l[i]=lower_bound(compress.begin(),compress.end(),l[i])-compress.begin();
    r[i]=lower_bound(compress.begin(),compress.end(),r[i])-compress.begin();
    //cout<<l[i]<<" "<<r[i]<<'\n';
    if(t[i]==1){
      upd(1,1,m,l[i],r[i],1);
    }else if(t[i]==2){
      upd(1,1,m,l[i],r[i],-1);
    }else{
      upd2(1,1,m,l[i],r[i]);
    }
    cout<<compress[F[1]]<<'\n';
  }
  return 0;
}
//2020.08.07 18:08:35


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;
const int maxn = 1e5;
int F[maxn * 6 * 4], G[maxn * 6 * 4];
int re[maxn * 6 * 4];
const int inf = 1e9;
void upd(int rt, int l, int r, int ll, int rr, int v) {
  if (ll <= l && rr >= r) {
    if (v == -1) {
      F[rt] = l, G[rt] = inf;
      re[rt] = v;
    } else if (v == 1) {
      F[rt] = inf, G[rt] = l;
      re[rt] = v;
    } else {
      swap(F[rt], G[rt]);
      if (re[rt] == 0)
        re[rt] = 2;
      else if (re[rt] == 2)
        re[rt] = 0;
      else if (re[rt] == -1)
        re[rt] = 1;
      else
        re[rt] = -1;
    }
    return;
  }
  int mid = (l + r) >> 1;
  if (re[rt] == -1) {
    re[rt << 1 | 1] = re[rt << 1] = -1;
    F[rt << 1] = l;
    F[rt << 1 | 1] = mid + 1;
    G[rt << 1] = inf;
    G[rt << 1 | 1] = inf;
    re[rt] = 0;
  }
  if (re[rt] == 1) {
    re[rt << 1] = re[rt << 1 | 1] = 1;
    F[rt << 1] = F[rt << 1 | 1] = inf;
    G[rt << 1] = l;
    G[rt << 1 | 1] = mid + 1;
    re[rt] = 0;
  }
  if (re[rt] == 2) {
    swap(F[rt << 1 | 1], G[rt << 1 | 1]);
    swap(F[rt << 1], G[rt << 1]);
    if (re[rt << 1] == 2)
      re[rt << 1] = 0;
    else if (re[rt << 1] == 1)
      re[rt << 1] = -1;
    else if (re[rt << 1] == 0)
      re[rt << 1] = 2;
    else
      re[rt << 1] = 1;
    if (re[rt << 1 | 1] == 2)
      re[rt << 1 | 1] = 0;
    else if (re[rt << 1 | 1] == 1)
      re[rt << 1 | 1] = -1;
    else if (re[rt << 1 | 1] == 0)
      re[rt << 1 | 1] = 2;
    else
      re[rt << 1 | 1] = 1;
    re[rt] = 0;
  }
  if (ll <= mid) upd(rt << 1, l, mid, ll, rr, v);
  if (rr > mid) upd(rt << 1 | 1, mid + 1, r, ll, rr, v);
  F[rt] = min(F[rt << 1], F[rt << 1 | 1]);
  G[rt] = min(G[rt << 1], G[rt << 1 | 1]);
}
int t[maxn], l[maxn], r[maxn];
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
  int n;
  cin >> n;
  vector<int> compress;
  for (int i = 0; i < n; ++i) {
    cin >> t[i] >> l[i] >> r[i];
    compress.push_back(l[i] + 1);
    compress.push_back(r[i] + 1);
    compress.push_back(l[i]);
    compress.push_back(r[i]);
    compress.push_back(l[i] - 1);
    compress.push_back(r[i] - 1);
  }
  compress.push_back(0);
  compress.push_back(1);
  compress.push_back(inf);
  sort(compress.begin(), compress.end());
  compress.erase(unique(compress.begin(), compress.end()), compress.end());
  int m = SZ(compress) - 1;
  upd(1, 1, m, 1, m, -1);
  for (int i = 0; i < n; ++i) {
    l[i] = lower_bound(compress.begin(), compress.end(), l[i]) - compress.begin();
    r[i] = lower_bound(compress.begin(), compress.end(), r[i]) - compress.begin();
    //cout << l[i] << " " << r[i] << '\n';
    if (t[i] == 1) {
      upd(1, 1, m, l[i], r[i], 1);
    } else if (t[i] == 2) {
      upd(1, 1, m, l[i], r[i], -1);
    } else {
      upd(1, 1, m, l[i], r[i], 2);
    }
    cout << compress[F[1]] << '\n';
    //cout << "tmp " << F[1] << "\n";
  }
  return 0;
}
//2020.08.07 18:08:35


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;
const int maxn = 1e5;
int F[maxn * 6 * 4], G[maxn * 6 * 4];
int re[maxn * 6 * 4];
const int64 inf = 1e18+2;
void upd(int rt, int l, int r, int ll, int rr, int v) {
  if (ll <= l && rr >= r) {
    if (v == -1) {
      F[rt] = l, G[rt] = inf;
      re[rt] = v;
    } else if (v == 1) {
      F[rt] = inf, G[rt] = l;
      re[rt] = v;
    } else {
      swap(F[rt], G[rt]);
      if (re[rt] == 0)
        re[rt] = 2;
      else if (re[rt] == 2)
        re[rt] = 0;
      else if (re[rt] == -1)
        re[rt] = 1;
      else
        re[rt] = -1;
    }
    return;
  }
  int mid = (l + r) >> 1;
  if (re[rt] == -1) {
    re[rt << 1 | 1] = re[rt << 1] = -1;
    F[rt << 1] = l;
    F[rt << 1 | 1] = mid + 1;
    G[rt << 1] = inf;
    G[rt << 1 | 1] = inf;
    re[rt] = 0;
  }
  if (re[rt] == 1) {
    re[rt << 1] = re[rt << 1 | 1] = 1;
    F[rt << 1] = F[rt << 1 | 1] = inf;
    G[rt << 1] = l;
    G[rt << 1 | 1] = mid + 1;
    re[rt] = 0;
  }
  if (re[rt] == 2) {
    swap(F[rt << 1 | 1], G[rt << 1 | 1]);
    swap(F[rt << 1], G[rt << 1]);
    if (re[rt << 1] == 2)
      re[rt << 1] = 0;
    else if (re[rt << 1] == 1)
      re[rt << 1] = -1;
    else if (re[rt << 1] == 0)
      re[rt << 1] = 2;
    else
      re[rt << 1] = 1;
    if (re[rt << 1 | 1] == 2)
      re[rt << 1 | 1] = 0;
    else if (re[rt << 1 | 1] == 1)
      re[rt << 1 | 1] = -1;
    else if (re[rt << 1 | 1] == 0)
      re[rt << 1 | 1] = 2;
    else
      re[rt << 1 | 1] = 1;
    re[rt] = 0;
  }
  if (ll <= mid) upd(rt << 1, l, mid, ll, rr, v);
  if (rr > mid) upd(rt << 1 | 1, mid + 1, r, ll, rr, v);
  F[rt] = min(F[rt << 1], F[rt << 1 | 1]);
  G[rt] = min(G[rt << 1], G[rt << 1 | 1]);
}
int t[maxn], l[maxn], r[maxn];
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
  int n;
  cin >> n;
  vector<int64> compress;
  for (int i = 0; i < n; ++i) {
    cin >> t[i] >> l[i] >> r[i];
    compress.push_back(l[i] + 1);
    compress.push_back(r[i] + 1);
    compress.push_back(l[i]);
    compress.push_back(r[i]);
    compress.push_back(l[i] - 1);
    compress.push_back(r[i] - 1);
  }
  compress.push_back(0);
  compress.push_back(1);
  compress.push_back(inf);
  sort(compress.begin(), compress.end());
  compress.erase(unique(compress.begin(), compress.end()), compress.end());
  int m = SZ(compress) - 1;
  upd(1, 1, m, 1, m, -1);
  for (int i = 0; i < n; ++i) {
    l[i] = lower_bound(compress.begin(), compress.end(), l[i]) - compress.begin();
    r[i] = lower_bound(compress.begin(), compress.end(), r[i]) - compress.begin();
    //cout << l[i] << " " << r[i] << '\n';
    if (t[i] == 1) {
      upd(1, 1, m, l[i], r[i], 1);
    } else if (t[i] == 2) {
      upd(1, 1, m, l[i], r[i], -1);
    } else {
      upd(1, 1, m, l[i], r[i], 2);
    }
    cout << compress[F[1]] << '\n';
    //cout << "tmp " << F[1] << "\n";
  }
  return 0;
}
//2020.08.07 18:08:35


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;
const int maxn = 1e5;
int64 F[maxn * 6 * 4], G[maxn * 6 * 4];
int re[maxn * 6 * 4];
const int64 inf = 1e18+2;
void upd(int rt, int l, int r, int ll, int rr, int v) {
  if (ll <= l && rr >= r) {
    if (v == -1) {
      F[rt] = l, G[rt] = inf;
      re[rt] = v;
    } else if (v == 1) {
      F[rt] = inf, G[rt] = l;
      re[rt] = v;
    } else {
      swap(F[rt], G[rt]);
      if (re[rt] == 0)
        re[rt] = 2;
      else if (re[rt] == 2)
        re[rt] = 0;
      else if (re[rt] == -1)
        re[rt] = 1;
      else
        re[rt] = -1;
    }
    return;
  }
  int mid = (l + r) >> 1;
  if (re[rt] == -1) {
    re[rt << 1 | 1] = re[rt << 1] = -1;
    F[rt << 1] = l;
    F[rt << 1 | 1] = mid + 1;
    G[rt << 1] = inf;
    G[rt << 1 | 1] = inf;
    re[rt] = 0;
  }
  if (re[rt] == 1) {
    re[rt << 1] = re[rt << 1 | 1] = 1;
    F[rt << 1] = F[rt << 1 | 1] = inf;
    G[rt << 1] = l;
    G[rt << 1 | 1] = mid + 1;
    re[rt] = 0;
  }
  if (re[rt] == 2) {
    swap(F[rt << 1 | 1], G[rt << 1 | 1]);
    swap(F[rt << 1], G[rt << 1]);
    if (re[rt << 1] == 2)
      re[rt << 1] = 0;
    else if (re[rt << 1] == 1)
      re[rt << 1] = -1;
    else if (re[rt << 1] == 0)
      re[rt << 1] = 2;
    else
      re[rt << 1] = 1;
    if (re[rt << 1 | 1] == 2)
      re[rt << 1 | 1] = 0;
    else if (re[rt << 1 | 1] == 1)
      re[rt << 1 | 1] = -1;
    else if (re[rt << 1 | 1] == 0)
      re[rt << 1 | 1] = 2;
    else
      re[rt << 1 | 1] = 1;
    re[rt] = 0;
  }
  if (ll <= mid) upd(rt << 1, l, mid, ll, rr, v);
  if (rr > mid) upd(rt << 1 | 1, mid + 1, r, ll, rr, v);
  F[rt] = min(F[rt << 1], F[rt << 1 | 1]);
  G[rt] = min(G[rt << 1], G[rt << 1 | 1]);
}
int64 t[maxn], l[maxn], r[maxn];
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false), cout.tie(0), cin.tie(0);
  int n;
  cin >> n;
  vector<int64> compress;
  for (int i = 0; i < n; ++i) {
    cin >> t[i] >> l[i] >> r[i];
    compress.push_back(l[i] + 1);
    compress.push_back(r[i] + 1);
    compress.push_back(l[i]);
    compress.push_back(r[i]);
    compress.push_back(l[i] - 1);
    compress.push_back(r[i] - 1);
  }
  compress.push_back(0);
  compress.push_back(1);
  compress.push_back(inf);
  sort(compress.begin(), compress.end());
  compress.erase(unique(compress.begin(), compress.end()), compress.end());
  int m = SZ(compress) - 1;
  upd(1, 1, m, 1, m, -1);
  for (int i = 0; i < n; ++i) {
    l[i] = lower_bound(compress.begin(), compress.end(), l[i]) - compress.begin();
    r[i] = lower_bound(compress.begin(), compress.end(), r[i]) - compress.begin();
    //cout << l[i] << " " << r[i] << '\n';
    if (t[i] == 1) {
      upd(1, 1, m, l[i], r[i], 1);
    } else if (t[i] == 2) {
      upd(1, 1, m, l[i], r[i], -1);
    } else {
      upd(1, 1, m, l[i], r[i], 2);
    }
    cout << compress[F[1]] << '\n';
    //cout << "tmp " << F[1] << "\n";
  }
  return 0;
}
//2020.08.07 18:08:35


#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 0x7fffffff

using namespace std;

typedef long long ll;

int minn[800000][2],setv[800000];
bool rev[800000];

void build(int l,int r,int o) {
  setv[o]=-1;minn[o][0]=l;minn[o][1]=inf;
  if (l==r) return;
  int m=((l+r)>>1);
  build(l,m,o*2);
  build(m+1,r,o*2+1);
}

void pushdown(int l,int r,int o) {
  int m=((l+r)>>1);
  if (setv[o]!=-1) {
    int p=setv[o];
    setv[o*2]=setv[o*2+1]=p;
    rev[o*2]=rev[o*2+1]=0;
    minn[o*2][p]=l;minn[o*2+1][p]=m+1;
    minn[o*2][p^1]=minn[o*2+1][p^1]=inf;
    setv[o]=-1;
  }
  if (rev[o]) {
    rev[o*2]^=1;rev[o*2+1]^=1;
    swap(minn[o*2][0],minn[o*2][1]);
    swap(minn[o*2+1][0],minn[o*2+1][1]);
    rev[o]=0;
  }
}

void update1(int l,int r,int o,int lx,int rx,int p) {
  if (l>=lx&&r<=rx) {
    setv[o]=p;rev[o]=0;
    minn[o][p]=l;minn[o][p^1]=inf;
  }
  else {
    pushdown(l,r,o);
    int m=((l+r)>>1);
    if (m>=lx) update1(l,m,o*2,lx,rx,p);
    if (m<rx) update1(m+1,r,o*2+1,lx,rx,p);
    minn[o][0]=min(minn[o*2][0],minn[o*2+1][0]);
    minn[o][1]=min(minn[o*2][1],minn[o*2+1][1]);
  }
}

void update2(int l,int r,int o,int lx,int rx) {
  if (l>=lx&&r<=rx) {
    rev[o]^=1;
    swap(minn[o][0],minn[o][1]);
  }
  else {
    pushdown(l,r,o);
    int m=((l+r)>>1);
    if (m>=lx) update2(l,m,o*2,lx,rx);
    if (m<rx) update2(m+1,r,o*2+1,lx,rx);
    minn[o][0]=min(minn[o*2][0],minn[o*2+1][0]);
    minn[o][1]=min(minn[o*2][1],minn[o*2+1][1]);
  }
}

struct Query {
  int kind;
  ll l,r;
  Query() {}
  Query(int a,ll b,ll c):kind(a),l(b),r(c) {}
};

Query q[100005];
ll pos[200005];

int main() {
  int n;
  scanf("%d",&n);
  int tot=0;
  for(int i=1;i<=n;i++) {
    int x;
    ll y=0,z=0;
    scanf("%d%lld%lld",&x,&y,&z);
    q[i]=Query(x,y,z);
    pos[++tot]=y;pos[++tot]=z+1;
  }
  pos[++tot]=1;
  sort(pos+1,pos+tot+1);
  build(1,tot,1);
  for(int i=1;i<=n;i++) {
    int l=lower_bound(pos+1,pos+tot+1,q[i].l)-pos;
    int r=lower_bound(pos+1,pos+tot+1,q[i].r+1)-pos-1;
    if (q[i].kind==1) update1(1,tot,1,l,r,1);
    else if (q[i].kind==2) update1(1,tot,1,l,r,0);
    else update2(1,tot,1,l,r);
    printf("%lld\n",pos[minn[1][0]]);
  }
  return 0;
}


#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int n,cnt,opt[100001],tag[400001],sum[400001];
ll ql[100001],qr[100001],dat[200001];
inline void merge(int t1,int &t2){
	if(t1<=1)t2=t1;
	else t2^=(t1&1);
}
inline void apply(int tag,int &sum,int l,int r){
	if(tag<=1)sum=tag*(r-l);
	else if(tag==3)sum=(r-l)-sum;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	merge(tag[o],tag[o<<1]);
	merge(tag[o],tag[o<<1|1]);
	apply(tag[o],sum[o<<1],l,mid);
	apply(tag[o],sum[o<<1|1],mid,r);
	tag[o]=2;
}
void update(int tg,int ql,int qr,int o,int l,int r){
	if(ql<=l&&r<=qr){
		merge(tg,tag[o]);
		apply(tag[o],sum[o],l,r);
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(ql<mid)update(tg,ql,qr,o<<1,l,mid);
	if(qr>mid)update(tg,ql,qr,o<<1|1,mid,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
int query(int o,int l,int r){
	if(l+1==r)return l;
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(sum[o<<1]<mid-l)return query(o<<1,l,mid);
	if(sum[o<<1|1]<r-mid)return query(o<<1|1,mid,r);
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%lld%lld",&opt[i],&ql[i],&qr[i]);
		dat[++cnt]=ql[i];
		dat[++cnt]=++qr[i];
	}
	sort(dat+1,dat+cnt+1);
	cnt=unique(dat+1,dat+cnt+1)-dat-1;
	dat[0]=dat[cnt];
	for(int i=1;i<=n;i++){
		int tg=(opt[i]==2?0:opt[i]),l=lower_bound(dat+1,dat+cnt+1,ql[i])-dat,r=lower_bound(dat+1,dat+cnt+1,qr[i])-dat;
		update(tg,l,r,1,1,cnt);
		printf("%lld\n",dat[query(1,1,cnt)]);
	}
}


#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int n,cnt,opt[100001],tag[400001]{2},sum[400001];
ll ql[100001],qr[100001],dat[200001];
inline void merge(int t1,int &t2){
	if(t1<=1)t2=t1;
	else t2^=(t1&1);
}
inline void apply(int tag,int &sum,int l,int r){
	if(tag<=1)sum=tag*(r-l);
	else if(tag==3)sum=(r-l)-sum;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	merge(tag[o],tag[o<<1]);
	merge(tag[o],tag[o<<1|1]);
	apply(tag[o],sum[o<<1],l,mid);
	apply(tag[o],sum[o<<1|1],mid,r);
	tag[o]=2;
}
void update(int tg,int ql,int qr,int o,int l,int r){
	if(ql<=l&&r<=qr){
		merge(tg,tag[o]);
		apply(tag[o],sum[o],l,r);
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(ql<mid)update(tg,ql,qr,o<<1,l,mid);
	if(qr>mid)update(tg,ql,qr,o<<1|1,mid,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
int query(int o,int l,int r){
	if(l+1==r)return l;
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(sum[o<<1]<mid-l)return query(o<<1,l,mid);
	if(sum[o<<1|1]<r-mid)return query(o<<1|1,mid,r);
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%lld%lld",&opt[i],&ql[i],&qr[i]);
		dat[++cnt]=ql[i];
		dat[++cnt]=++qr[i];
	}
	sort(dat+1,dat+cnt+1);
	cnt=unique(dat+1,dat+cnt+1)-dat-1;
	dat[0]=dat[cnt];
	for(int i=1;i<=n;i++){
		int tg=(opt[i]==2?0:opt[i]),l=lower_bound(dat+1,dat+cnt+1,ql[i])-dat,r=lower_bound(dat+1,dat+cnt+1,qr[i])-dat;
		update(tg,l,r,1,1,cnt);
		printf("%lld\n",dat[query(1,1,cnt)]);
	}
}


#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int n,cnt,opt[100001],tag[800008]{2},sum[800008];
ll ql[100001],qr[100001],dat[200002];
inline void merge(int t1,int &t2){
	if(t1<=1)t2=t1;
	else t2^=(t1&1);
}
inline void apply(int tag,int &sum,int l,int r){
	if(tag<=1)sum=tag*(r-l);
	else if(tag==3)sum=(r-l)-sum;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	merge(tag[o],tag[o<<1]);
	merge(tag[o],tag[o<<1|1]);
	apply(tag[o],sum[o<<1],l,mid);
	apply(tag[o],sum[o<<1|1],mid,r);
	tag[o]=2;
}
void update(int tg,int ql,int qr,int o,int l,int r){
	if(ql<=l&&r<=qr){
		merge(tg,tag[o]);
		apply(tg,sum[o],l,r);
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(ql<mid)update(tg,ql,qr,o<<1,l,mid);
	if(qr>mid)update(tg,ql,qr,o<<1|1,mid,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
int query(int o,int l,int r){
	if(l+1==r)return sum[o]==1?0:l;
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(sum[o<<1]<mid-l)return query(o<<1,l,mid);
	if(sum[o<<1|1]<r-mid)return query(o<<1|1,mid,r);
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%lld%lld",&opt[i],&ql[i],&qr[i]);
		dat[++cnt]=ql[i];
		dat[++cnt]=++qr[i];
	}
	dat[++cnt]=1;
	sort(dat+1,dat+cnt+1);
	cnt=unique(dat+1,dat+cnt+1)-dat-1;
	dat[0]=dat[cnt];
	for(int i=1;i<=n;i++){
		int tg=(opt[i]==2?0:opt[i]),l=lower_bound(dat+1,dat+cnt+1,ql[i])-dat,r=lower_bound(dat+1,dat+cnt+1,qr[i])-dat;
		update(tg,l,r,1,1,cnt);
		printf("%lld\n",dat[query(1,1,cnt)]);
	}
}


#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int n,cnt,opt[100001],tag[400001]{2},sum[400001];
ll ql[100001],qr[100001],dat[200001];
inline void merge(int t1,int &t2){
	if(t1<=1)t2=t1;
	else t2^=(t1&1);
}
inline void apply(int tag,int &sum,int l,int r){
	if(tag<=1)sum=tag*(r-l);
	else if(tag==3)sum=(r-l)-sum;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	merge(tag[o],tag[o<<1]);
	merge(tag[o],tag[o<<1|1]);
	apply(tag[o],sum[o<<1],l,mid);
	apply(tag[o],sum[o<<1|1],mid,r);
	tag[o]=2;
}
void update(int tg,int ql,int qr,int o,int l,int r){
	if(ql<=l&&r<=qr){
		merge(tg,tag[o]);
		apply(tg,sum[o],l,r);
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(ql<mid)update(tg,ql,qr,o<<1,l,mid);
	if(qr>mid)update(tg,ql,qr,o<<1|1,mid,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
int query(int o,int l,int r){
	if(l+1==r)return l;
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(sum[o<<1]<mid-l)return query(o<<1,l,mid);
	if(sum[o<<1|1]<r-mid)return query(o<<1|1,mid,r);
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%lld%lld",&opt[i],&ql[i],&qr[i]);
		dat[++cnt]=ql[i];
		dat[++cnt]=++qr[i];
	}
	sort(dat+1,dat+cnt+1);
	cnt=unique(dat+1,dat+cnt+1)-dat-1;
	dat[0]=dat[cnt];
	for(int i=1;i<=n;i++){
		int tg=(opt[i]==2?0:opt[i]),l=lower_bound(dat+1,dat+cnt+1,ql[i])-dat,r=lower_bound(dat+1,dat+cnt+1,qr[i])-dat;
		update(tg,l,r,1,1,cnt);
		printf("%lld\n",dat[query(1,1,cnt)]);
	}
}


#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int n,cnt,opt[100001],tag[400001]{2},sum[400001];
ll ql[100001],qr[100001],dat[200001];
inline void merge(int t1,int &t2){
	if(t1<=1)t2=t1;
	else t2^=(t1&1);
}
inline void apply(int tag,int &sum,int l,int r){
	if(tag<=1)sum=tag*(r-l);
	else if(tag==3)sum=(r-l)-sum;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	merge(tag[o],tag[o<<1]);
	merge(tag[o],tag[o<<1|1]);
	apply(tag[o],sum[o<<1],l,mid);
	apply(tag[o],sum[o<<1|1],mid,r);
	tag[o]=2;
}
void update(int tg,int ql,int qr,int o,int l,int r){
	if(ql<=l&&r<=qr){
		merge(tg,tag[o]);
		apply(tg,sum[o],l,r);
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(ql<mid)update(tg,ql,qr,o<<1,l,mid);
	if(qr>mid)update(tg,ql,qr,o<<1|1,mid,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
int query(int o,int l,int r){
	if(l+1==r)return sum[o]==1?0:l;
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(sum[o<<1]<mid-l)return query(o<<1,l,mid);
	if(sum[o<<1|1]<r-mid)return query(o<<1|1,mid,r);
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%lld%lld",&opt[i],&ql[i],&qr[i]);
		dat[++cnt]=ql[i];
		dat[++cnt]=++qr[i];
	}
	sort(dat+1,dat+cnt+1);
	cnt=unique(dat+1,dat+cnt+1)-dat-1;
	dat[0]=dat[cnt];
	for(int i=1;i<=n;i++){
		int tg=(opt[i]==2?0:opt[i]),l=lower_bound(dat+1,dat+cnt+1,ql[i])-dat,r=lower_bound(dat+1,dat+cnt+1,qr[i])-dat;
		update(tg,l,r,1,1,cnt);
		printf("%lld\n",dat[query(1,1,cnt)]);
	}
}


#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int n,cnt,opt[100001],tag[800001]{2},sum[800001];
ll ql[100001],qr[100001],dat[200001];
inline void merge(int t1,int &t2){
	if(t1<=1)t2=t1;
	else t2^=(t1&1);
}
inline void apply(int tag,int &sum,int l,int r){
	if(tag<=1)sum=tag*(r-l);
	else if(tag==3)sum=(r-l)-sum;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	merge(tag[o],tag[o<<1]);
	merge(tag[o],tag[o<<1|1]);
	apply(tag[o],sum[o<<1],l,mid);
	apply(tag[o],sum[o<<1|1],mid,r);
	tag[o]=2;
}
void update(int tg,int ql,int qr,int o,int l,int r){
	if(ql<=l&&r<=qr){
		merge(tg,tag[o]);
		apply(tg,sum[o],l,r);
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(ql<mid)update(tg,ql,qr,o<<1,l,mid);
	if(qr>mid)update(tg,ql,qr,o<<1|1,mid,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
int query(int o,int l,int r){
	if(l+1==r)return sum[o]==1?0:l;
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(sum[o<<1]<mid-l)return query(o<<1,l,mid);
	if(sum[o<<1|1]<r-mid)return query(o<<1|1,mid,r);
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%lld%lld",&opt[i],&ql[i],&qr[i]);
		dat[++cnt]=ql[i];
		dat[++cnt]=++qr[i];
	}
	sort(dat+1,dat+cnt+1);
	cnt=unique(dat+1,dat+cnt+1)-dat-1;
	dat[0]=dat[cnt];
	for(int i=1;i<=n;i++){
		int tg=(opt[i]==2?0:opt[i]),l=lower_bound(dat+1,dat+cnt+1,ql[i])-dat,r=lower_bound(dat+1,dat+cnt+1,qr[i])-dat;
		update(tg,l,r,1,1,cnt);
		printf("%lld\n",dat[query(1,1,cnt)]);
	}
}


#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int n,cnt,opt[100001],tag[400001]{2},sum[400001];
ll ql[100001],qr[100001],dat[200001];
inline void merge(int t1,int &t2){
	if(t1<=1)t2=t1;
	else t2^=(t1&1);
}
inline void apply(int tag,int &sum,int l,int r){
	if(tag<=1)sum=tag*(r-l);
	else if(tag==3)sum=(r-l)-sum;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	merge(tag[o],tag[o<<1]);
	merge(tag[o],tag[o<<1|1]);
	apply(tag[o],sum[o<<1],l,mid);
	apply(tag[o],sum[o<<1|1],mid,r);
	tag[o]=2;
}
void update(int tg,int ql,int qr,int o,int l,int r){
	if(ql<=l&&r<=qr){
		merge(tg,tag[o]);
		apply(tag[o],sum[o],l,r);
		return;
	}
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(ql<mid)update(tg,ql,qr,o<<1,l,mid);
	if(qr>mid)update(tg,ql,qr,o<<1|1,mid,r);
	sum[o]=sum[o<<1]+sum[o<<1|1];
}
int query(int o,int l,int r){
	if(l+1==r)return sum[o]==1?0:l;
	pushdown(o,l,r);
	int mid=(l+r)>>1;
	if(sum[o<<1]<mid-l)return query(o<<1,l,mid);
	if(sum[o<<1|1]<r-mid)return query(o<<1|1,mid,r);
	return 0;
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%lld%lld",&opt[i],&ql[i],&qr[i]);
		dat[++cnt]=ql[i];
		dat[++cnt]=++qr[i];
	}
	sort(dat+1,dat+cnt+1);
	cnt=unique(dat+1,dat+cnt+1)-dat-1;
	dat[0]=dat[cnt];
	for(int i=1;i<=n;i++){
		int tg=(opt[i]==2?0:opt[i]),l=lower_bound(dat+1,dat+cnt+1,ql[i])-dat,r=lower_bound(dat+1,dat+cnt+1,qr[i])-dat;
		update(tg,l,r,1,1,cnt);
		printf("%lld\n",dat[query(1,1,cnt)]);
	}
}


#include <bits/stdc++.h>
using namespace std;
#define LL long long

int n;
int t[100005];
LL li[100005], ri[100005];
set < LL > S;
vector < LL > comp;
int sz[300005*4], On[300005*4], Rev[300005*4], Apply[300005*4];
int N;

int gv ( LL x ){
	return lower_bound(comp.begin(),comp.end(),x) - comp.begin();
}

void build( int p, int s, int e ){
	Apply[p] = -1;
	sz[p] = e - s + 1;
	if ( s == e ) {
		On[p] = 0;
		return;
	}
	int m = ( s + e) >> 1;
	build(p*2+1,s,m);
	build(p*2+2,m+1,e);
	On[p] = On[p*2+2] + On[p*2+1];
}

void pd( int p ){
	if ( Apply[p] >= 0 ){
		Apply[p*2+1] = Apply[p*2+2] = Apply[p];
		if ( Apply[p] ){
			On[p*2+1] = sz[p*2+1];
			On[p*2+2] = sz[p*2+2];
		} else {
			On[p*2+1] = On[p*2+2] = 0;
		}
		Apply[p] = -1;
		Rev[p] = 0;
	}

	if ( Rev[p] ){
		Rev[p*2+1] ^= 1;
		Rev[p*2+2] ^= 1;
		On[p*2+1] = sz[p*2+1] - On[p*2+1];
		On[p*2+2] = sz[p*2+2] - On[p*2+2];
		Rev[p] ^= 1;
	}
}

void Set( int p, int s, int e, int l, int r, int v ){
	if ( s < e ) pd(p);

	if ( s > r || e < l ) return;
	if ( l <= s && e <= r ){
		if ( v ){
			Apply[p] = 1;
			On[p] = sz[p];
		} else {
			Apply[p] = 0;
			On[p] = 0;
		}
		return;
	}

	int m = ( s + e ) >> 1;
	Set(p*2+1,s,m,l,r,v);
	Set(p*2+2,m+1,e,l,r,v);
	On[p] = On[p*2+1] + On[p*2+2];
}

void Reverse( int p, int s, int e, int l, int r ){
	if ( s < e ) pd(p);
	if ( s > r || e < l ) return;
	if ( l <= s && e <= r ){
		Rev[p] = 1;
		On[p] = sz[p] - On[p];
		return;
	}
	int m =( s + e ) >> 1;
	Reverse(p*2+1,s,m,l,r);
	Reverse(p*2+2,m+1,e,l,r);
	On[p] = On[p*2+1] + On[p*2+2];
}

LL Mex( int p , int s, int e ){
	if ( s < e ) pd(p);
	if ( s == e ) return comp[s];
	int m = ( s + e ) / 2;
	if ( sz[p*2+1] != On[p*2+1] ) return Mex(p*2+1,s,m);
	return Mex(p*2+2,m+1,e);
}

int main(){

	scanf("%d",&n);
	for ( int i = 1; i <= n; i++ ){
		scanf("%d%lld%lld",&t[i],&li[i],&ri[i]);
		S.insert(li[i]);
		S.insert(ri[i]);
		S.insert(ri[i]+1);
	}
	S.insert(1);
	for ( auto it : S ) comp.push_back(it);
	N = comp.size();
	build(0,0,N-1);

	for ( int i = 1; i <= n; i++ ){
		if ( t[i] == 1 ){
			Set(0,0,N-1,gv(li[i]), gv(ri[i]), 1);
		} else if ( t[i] == 2 ){
			Set(0,0,N-1,gv(li[i]), gv(ri[i]), 0);
		} else if ( t[i] == 3 ){
			Reverse(0,0,N-1,gv(li[i]), gv(ri[i]));
		}
		printf("%lld\n",Mex(0,0,N-1));
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define LL long long

int n;
int t[100005];
LL li[100005], ri[100005];
set < LL > S;
vector < LL > comp;
int sz[300005*4], On[300005*4], Rev[300005*4], Apply[300005*4];
int N;

int gv ( LL x ){
	return lower_bound(comp.begin(),comp.end(),x) - comp.begin();
}

void build( int p, int s, int e ){
	Apply[p] = -1;
	sz[p] = e - s + 1;
	if ( s == e ) {
		On[p] = 0;
		return;
	}
	int m = ( s + e) >> 1;
	build(p*2+1,s,m);
	build(p*2+2,m+1,e);
	On[p] = On[p*2+2] + On[p*2+1];
}

void pd( int p ){
	if ( Rev[p] ){
		Rev[p*2+1] ^= 1;
		Rev[p*2+2] ^= 1;
		On[p*2+1] = sz[p*2+1] - On[p*2+1];
		On[p*2+2] = sz[p*2+2] - On[p*2+2];
		Rev[p] ^= 1;
	}

	if ( Apply[p] >= 0 ){
		Apply[p*2+1] = Apply[p*2+2] = Apply[p];
		if ( Apply[p] ){
			On[p*2+1] = sz[p*2+1];
			On[p*2+2] = sz[p*2+2];
		} else {
			On[p*2+1] = On[p*2+2] = 0;
		}
		Apply[p] = -1;
	}
}

void Set( int p, int s, int e, int l, int r, int v ){
	if ( s < e ) pd(p);

	if ( s > r || e < l ) return;
	if ( l <= s && e <= r ){
		if ( v ){
			Apply[p] = 1;
			On[p] = sz[p];
		} else {
			Apply[p] = 0;
			On[p] = 0;
		}
		Rev[p] = 0;
		return;
	}

	int m = ( s + e ) >> 1;
	Set(p*2+1,s,m,l,r,v);
	Set(p*2+2,m+1,e,l,r,v);
	On[p] = On[p*2+1] + On[p*2+2];
}

void Reverse( int p, int s, int e, int l, int r ){
	if ( s < e ) pd(p);
	if ( s > r || e < l ) return;
	if ( l <= s && e <= r ){
		Rev[p] = 1;
		On[p] = sz[p] - On[p];
		return;
	}
	int m =( s + e ) >> 1;
	Reverse(p*2+1,s,m,l,r);
	Reverse(p*2+2,m+1,e,l,r);
	On[p] = On[p*2+1] + On[p*2+2];
}

LL Mex( int p , int s, int e ){
	if ( s < e ) pd(p);
	if ( s == e ) return comp[s];
	int m = ( s + e ) / 2;
	if ( sz[p*2+1] != On[p*2+1] ) return Mex(p*2+1,s,m);
	return Mex(p*2+2,m+1,e);
}

int main(){

	scanf("%d",&n);
	for ( int i = 1; i <= n; i++ ){
		scanf("%d%lld%lld",&t[i],&li[i],&ri[i]);
		S.insert(li[i]);
		S.insert(ri[i]);
		S.insert(ri[i]+1);
	}
	S.insert(1);
	for ( auto it : S ) comp.push_back(it);
	N = comp.size();
	build(0,0,N-1);

	for ( int i = 1; i <= n; i++ ){
		if ( t[i] == 1 ){
			Set(0,0,N-1,gv(li[i]), gv(ri[i]), 1);
		} else if ( t[i] == 2 ){
			Set(0,0,N-1,gv(li[i]), gv(ri[i]), 0);
		} else if ( t[i] == 3 ){
			Reverse(0,0,N-1,gv(li[i]), gv(ri[i]));
		}
		printf("%lld\n",Mex(0,0,N-1));
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define LL long long

int n;
int t[100005];
LL li[100005], ri[100005];
set < LL > S;
vector < LL > comp;
int sz[300005*4], On[300005*4], Rev[300005*4], Apply[300005*4];
int N;

int gv ( LL x ){
	return lower_bound(comp.begin(),comp.end(),x) - comp.begin();
}

void build( int p, int s, int e ){
	Apply[p] = -1;
	sz[p] = e - s + 1;
	if ( s == e ) {
		On[p] = 0;
		return;
	}
	int m = ( s + e) >> 1;
	build(p*2+1,s,m);
	build(p*2+2,m+1,e);
	On[p] = On[p*2+2] + On[p*2+1];
}

void pd( int p ){

	if ( Apply[p] >= 0 ){
		Apply[p*2+1] = Apply[p*2+2] = Apply[p];
		Rev[p*2+1] = Rev[p*2+2] = 0;
		if ( Apply[p] ){
			On[p*2+1] = sz[p*2+1];
			On[p*2+2] = sz[p*2+2];
		} else {
			On[p*2+1] = On[p*2+2] = 0;
		}
		Apply[p] = -1;
	}

	if ( Rev[p] ){
		Rev[p*2+1] ^= 1;
		Rev[p*2+2] ^= 1;
		On[p*2+1] = sz[p*2+1] - On[p*2+1];
		On[p*2+2] = sz[p*2+2] - On[p*2+2];
		Rev[p] ^= 1;
	}
}

void Set( int p, int s, int e, int l, int r, int v ){
	if ( s < e ) pd(p);

	if ( s > r || e < l ) return;
	if ( l <= s && e <= r ){
		if ( v ){
			Apply[p] = 1;
			On[p] = sz[p];
		} else {
			Apply[p] = 0;
			On[p] = 0;
		}
		Rev[p] = 0;
		return;
	}

	int m = ( s + e ) >> 1;
	Set(p*2+1,s,m,l,r,v);
	Set(p*2+2,m+1,e,l,r,v);
	On[p] = On[p*2+1] + On[p*2+2];
}

void Reverse( int p, int s, int e, int l, int r ){
	if ( s < e ) pd(p);
	if ( s > r || e < l ) return;
	if ( l <= s && e <= r ){
		Rev[p] = 1;
		On[p] = sz[p] - On[p];
		return;
	}
	int m =( s + e ) >> 1;
	Reverse(p*2+1,s,m,l,r);
	Reverse(p*2+2,m+1,e,l,r);
	On[p] = On[p*2+1] + On[p*2+2];
}

LL Mex( int p , int s, int e ){
	if ( s < e ) pd(p);
	if ( s == e ) return comp[s];
	int m = ( s + e ) / 2;
	if ( sz[p*2+1] != On[p*2+1] ) return Mex(p*2+1,s,m);
	return Mex(p*2+2,m+1,e);
}

int main(){

	scanf("%d",&n);
	for ( int i = 1; i <= n; i++ ){
		scanf("%d%lld%lld",&t[i],&li[i],&ri[i]);
		S.insert(li[i]);
		S.insert(ri[i]);
		S.insert(ri[i]+1);
	}
	S.insert(1);
	for ( auto it : S ) comp.push_back(it);
	N = comp.size();
	build(0,0,N-1);

	for ( int i = 1; i <= n; i++ ){
		if ( t[i] == 1 ){
			Set(0,0,N-1,gv(li[i]), gv(ri[i]), 1);
		} else if ( t[i] == 2 ){
			Set(0,0,N-1,gv(li[i]), gv(ri[i]), 0);
		} else if ( t[i] == 3 ){
			Reverse(0,0,N-1,gv(li[i]), gv(ri[i]));
		}
		printf("%lld\n",Mex(0,0,N-1));
	}
	return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef long double ld;
const int N = 100006;
const int nein = -1;

struct qr {
    int o, l, r;
};

vector<int> vals;
vector<qr> q;

struct Segment_Tree {

    vector<int> val, lazy;
    int size;

    void init(int x) {
        size = 1;
        while(size < x) size *= 2;
        val.resize(size * 2);
        lazy.resize(size * 2);
    }

    void propagate(int node, int l, int r) {

        if (l == r - 1) {
            lazy[node] = nein;
            return;
        }

        if (lazy[node] == nein) {
            return;
        }

        int mid = (l + r) / 2;
        for(int x : {2 * node + 1, 2 * node + 2}) {

               if (lazy[node] == 0) {
                    val[x] = 0;
                    lazy[x] = 0;
               }

               if (lazy[node] == 1) {
                    val[x] = mid - l;
                    lazy[x] = 1;
               }

               if (lazy[node] == 2) {
                    val[x] = mid - l - val[x];
                    lazy[x] = 1 - lazy[x];
               }
        }

        lazy[node] = nein;

    }
    int merge(int a, int b) {
        return a + b;
    }

    void add(int node, int l, int r, int lf, int rg, int x) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = x * (r - l);
            lazy[node] = x;
            return;
        }

        int mid = (l + r) / 2;

        add(node * 2 + 1, l, mid, lf, rg, x);
        add(node * 2 + 2, mid, r, lf, rg, x);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void add(int l, int r, int x) {
        add(0, 0, size, l, r, x);
    }

    void rev(int node, int l, int r, int lf, int rg) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = r - l - val[node];
            if (lazy[node] == -1) lazy[node] = 2; else lazy[node] = 1 - lazy[node];
            return;
        }

        int mid = (l + r) / 2;

        rev(node * 2 + 1, l, mid, lf, rg);
        rev(node * 2 + 2, mid, r, lf, rg);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void rev(int l, int r) {
        rev(0, 0, size, l, r);
    }

    int get(int node, int l, int r) {

        propagate(node, l, r);
        if (val[node] == r - l) return -1;
        if (l == r - 1) {
            return l;
        }

        int mid = (l + r) / 2;
        int ans = get(node * 2 + 1, l, mid);
        if (ans == -1) ans = get(node * 2 + 2, mid, r);

        return ans;

    }

    int get() {
        return get(0, 0, size);
    }

};
int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;

    for(int i = 1; i <= n; i++) {
        int op, x, y;
        cin >> op >> x >> y;
        q.pb(qr{op, x, y});
        vals.pb(x);
        vals.pb(y);
        vals.pb(y + 1);
    }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

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

        q[i - 1].l = lower_bound(vals.begin(), vals.end(), q[i - 1].l) - vals.begin();
        q[i - 1].r = lower_bound(vals.begin(), vals.end(), q[i - 1].r) - vals.begin();

    }

    Segment_Tree st;
    st.init(6 * n);

    for(auto it : q) {

        // cout << it.l << ' ' << it.r << '\n';

        if (it.o == 1) {
            st.add(it.l, it.r + 1, 1);
        } else if (it.o == 2) {
            st.add(it.l, it.r + 1, 0);
        } else if (it.o == 3) {
            st.rev(it.l, it.r + 1);
        }

        // cout << st.val[0] << '\n';
        //cout << st.get() << '\n';
        // cout << "ska\n";
        cout << vals[st.get()] << '\n';

    }
    return 0;
}

// 5
// 3 1 4
// 3 1 4
// 1 1 2
// 1 1 2
// 3 1 2

// 5
// 5
// 5
// 5
// 1


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef long double ld;
const int N = 100006;
const int nein = -1;

struct qr {
    int o, l, r;
};

map<int, int> h;
vector<int> vals;
vector<qr> q;

struct Segment_Tree {

    vector<int> val, lazy;
    int size;

    void init(int x) {
        size = 1;
        while(size < x) size *= 2;
        val.resize(size * 2);
        lazy.resize(size * 2);
    }

    void propagate(int node, int l, int r) {

        if (l == r - 1) {
            lazy[node] = nein;
            return;
        }

        if (lazy[node] == nein) {
            return;
        }

        int mid = (l + r) / 2;
        for(int x : {2 * node + 1, 2 * node + 2}) {

            if (lazy[node] < 2) val[x] = lazy[node] * (mid - l);
            else val[x] = mid - l - val[x];

            lazy[x] = lazy[node];
        }

        lazy[node] = nein;

    }
    int merge(int a, int b) {
        return a + b;
    }

    void add(int node, int l, int r, int lf, int rg, int x) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = x * (r - l);
            lazy[node] = x;
            return;
        }

        int mid = (l + r) / 2;

        add(node * 2 + 1, l, mid, lf, rg, x);
        add(node * 2 + 2, mid, r, lf, rg, x);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void add(int l, int r, int x) {
        add(0, 0, size, l, r, x);
    }

    void rev(int node, int l, int r, int lf, int rg) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = r - l - val[node];
            lazy[node] = 2;
            return;
        }

        int mid = (l + r) / 2;

        rev(node * 2 + 1, l, mid, lf, rg);
        rev(node * 2 + 2, mid, r, lf, rg);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void rev(int l, int r) {
        rev(0, 0, size, l, r);
    }

    int get(int node, int l, int r) {

        propagate(node, l, r);

        if (val[node] == r - l) return -1;

        if (l == r - 1) {
            return l;
        }

        int mid = (l + r) / 2;
        int ans = get(node * 2 + 1, l, mid);
        if (ans == -1) ans = get(node * 2 + 2, mid, r);

        return ans;

    }

    int get() {
        return get(0, 0, size);
    }

};
int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;

    for(int i = 1; i <= n; i++) {
        int op, x, y;
        cin >> op >> x >> y;
        q.pb(qr{op, x, y});
        vals.pb(x);
        vals.pb(y);
        vals.pb(y + 1);
    }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

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

        q[i - 1].l = lower_bound(vals.begin(), vals.end(), q[i - 1].l) - vals.begin();
        q[i - 1].r = lower_bound(vals.begin(), vals.end(), q[i - 1].r) - vals.begin();

    }

    Segment_Tree st;
    st.init(5 * n);

    for(auto it : q) {

        // cout << it.l << ' ' << it.r << '\n';

        if (it.o == 1) {
            st.add(it.l, it.r + 1, 1);
        } else if (it.o == 2) {
            st.add(it.l, it.r + 1, 0);
        } else if (it.o == 3) {
            st.rev(it.l, it.r + 1);
        }

        // cout << "ska\n";
        cout << vals[st.get()] << '\n';

    }
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef long double ld;
const int N = 100006;
const int nein = -1;

struct qr {
    int o, l, r;
};

map<int, int> h;
vector<int> vals;
vector<qr> q;

struct Segment_Tree {

    vector<int> val, lazy;
    int size;

    void init(int x) {
        size = 1;
        while(size < x) size *= 2;
        val.resize(size * 2);
        lazy.resize(size * 2);
    }

    void propagate(int node, int l, int r) {

        if (l == r - 1) {
            lazy[node] = nein;
            return;
        }

        if (lazy[node] == nein) {
            return;
        }

        int mid = (l + r) / 2;
        for(int x : {2 * node + 1, 2 * node + 2}) {

            if (lazy[node] < 2) val[x] = lazy[node] * (mid - l);
            else val[x] = mid - l - val[x];

            lazy[x] = lazy[node];
        }

        lazy[node] = nein;

    }
    int merge(int a, int b) {
        return a + b;
    }

    void add(int node, int l, int r, int lf, int rg, int x) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = x * (r - l);
            lazy[node] = x;
            return;
        }

        int mid = (l + r) / 2;

        add(node * 2 + 1, l, mid, lf, rg, x);
        add(node * 2 + 2, mid, r, lf, rg, x);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void add(int l, int r, int x) {
        add(0, 0, size, l, r, x);
    }

    void rev(int node, int l, int r, int lf, int rg) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = r - l - val[node];
            lazy[node] = 2;
            return;
        }

        int mid = (l + r) / 2;

        rev(node * 2 + 1, l, mid, lf, rg);
        rev(node * 2 + 2, mid, r, lf, rg);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void rev(int l, int r) {
        rev(0, 0, size, l, r);
    }

    int get(int node, int l, int r) {

        propagate(node, l, r);

        if (val[node] == r - l) return -1;

        if (l == r - 1) {
            return l;
        }

        int mid = (l + r) / 2;
        int ans = get(node * 2 + 1, l, mid);
        if (ans == -1) ans = get(node * 2 + 2, mid, r);

        return ans;

    }

    int get() {
        return get(0, 0, size);
    }

};
int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    int mx1 = 0;

    for(int i = 1; i <= n; i++) {
        int op, x, y;
        cin >> op >> x >> y;
        mx1 = max({mx1, x, y});
        q.pb(qr{op, x, y});
        vals.pb(x);
        vals.pb(y);
    }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

    int mx = 0;

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

        int temp = q[i - 1].l;
        q[i - 1].l = lower_bound(vals.begin(), vals.end(), q[i - 1].l) - vals.begin();
        h[q[i - 1].l] = temp;

        temp = q[i - 1].r;
        q[i - 1].r = lower_bound(vals.begin(), vals.end(), q[i - 1].r) - vals.begin();
        h[q[i - 1].r] = temp;
        mx = max({mx, q[i - 1].l, q[i - 1].r});
    }

    Segment_Tree st;
    st.init(3 * n);

    h[mx + 1] = mx1 + 1;

    for(auto it : q) {

        // cout << it.l << ' ' << it.r << '\n';

        if (it.o == 1) {
            st.add(it.l, it.r + 1, 1);
        } else if (it.o == 2) {
            st.add(it.l, it.r + 1, 0);
        } else if (it.o == 3) {
            st.rev(it.l, it.r + 1);
        }

        // cout << "ska\n";
        cout << h[st.get()] << '\n';

    }
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef long double ld;
const int N = 100006;
const int nein = -1;

struct qr {
    int o, l, r;
};

map<int, int> h;
vector<int> vals;
vector<qr> q;

struct Segment_Tree {

    vector<int> val, lazy;
    int size;

    void init(int x) {
        size = 1;
        while(size < x) size *= 2;
        val.resize(size * 2);
        lazy.resize(size * 2);
    }

    void propagate(int node, int l, int r) {

        if (l == r - 1) {
            lazy[node] = nein;
            return;
        }

        if (lazy[node] == nein) {
            return;
        }

        int mid = (l + r) / 2;
        for(int x : {2 * node + 1, 2 * node + 2}) {

            if (lazy[node] < 2) val[x] = lazy[node] * (mid - l);
            else val[x] = mid - l - val[x];

            lazy[x] = lazy[node];
        }

        lazy[node] = nein;

    }
    int merge(int a, int b) {
        return a + b;
    }

    void add(int node, int l, int r, int lf, int rg, int x) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = x * (r - l);
            lazy[node] = x;
            return;
        }

        int mid = (l + r) / 2;

        add(node * 2 + 1, l, mid, lf, rg, x);
        add(node * 2 + 2, mid, r, lf, rg, x);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void add(int l, int r, int x) {
        add(0, 0, size, l, r, x);
    }

    void rev(int node, int l, int r, int lf, int rg) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = r - l - val[node];
            lazy[node] = 2;
            return;
        }

        int mid = (l + r) / 2;

        rev(node * 2 + 1, l, mid, lf, rg);
        rev(node * 2 + 2, mid, r, lf, rg);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void rev(int l, int r) {
        rev(0, 0, size, l, r);
    }

    int get(int node, int l, int r) {

        propagate(node, l, r);

        if (val[node] == r - l) return -1;

        if (l == r - 1) {
            return l;
        }

        int mid = (l + r) / 2;
        int ans = get(node * 2 + 1, l, mid);
        if (ans == -1) ans = get(node * 2 + 2, mid, r);

        return ans;

    }

    int get() {
        return get(0, 0, size);
    }

};
int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;

    for(int i = 1; i <= n; i++) {
        int op, x, y;
        cin >> op >> x >> y;
        q.pb(qr{op, x, y});
        vals.pb(x);
        vals.pb(y);
    }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

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

        int temp = q[i - 1].l;
        q[i - 1].l = lower_bound(vals.begin(), vals.end(), q[i - 1].l) - vals.begin();
        h[q[i - 1].l] = temp;

        temp = q[i - 1].r;
        q[i - 1].r = lower_bound(vals.begin(), vals.end(), q[i - 1].r) - vals.begin();
        h[q[i - 1].r] = temp;

    }

    Segment_Tree st;
    st.init(3 * n);

    for(auto it : q) {

        // cout << it.l << ' ' << it.r << '\n';

        if (it.o == 1) {
            st.add(it.l, it.r + 1, 1);
        } else if (it.o == 2) {
            st.add(it.l, it.r + 1, 0);
        } else if (it.o == 3) {
            st.rev(it.l, it.r + 1);
        }

        // cout << "ska\n";
        cout << h[st.get()] << '\n';

    }
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef long double ld;
const int N = 100006;
const int nein = -1;

struct qr {
    ll o, l, r;
};

vector<ll> vals;
vector<qr> q;

struct Segment_Tree {

    vector<int> val, lazy;
    int size;

    void init(int x) {
        size = 1;
        while(size < x) size *= 2;
        val.resize(size * 2);
        lazy.resize(size * 2);
    }

    void propagate(int node, int l, int r) {

        if (l == r - 1) {
            lazy[node] = nein;
            return;
        }

        if (lazy[node] == nein) {
            return;
        }

        int mid = (l + r) / 2;
        for(int x : {2 * node + 1, 2 * node + 2}) {

               if (lazy[node] == 0) {
                    val[x] = 0;
                    lazy[x] = 0;
               }

               if (lazy[node] == 1) {
                    val[x] = mid - l;
                    lazy[x] = 1;
               }

               if (lazy[node] == 2) {
                    val[x] = mid - l - val[x];
                    lazy[x] = 1 - lazy[x];
               }
        }

        lazy[node] = nein;

    }
    int merge(int a, int b) {
        return a + b;
    }

    void add(int node, int l, int r, int lf, int rg, int x) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = x * (r - l);
            lazy[node] = x;
            return;
        }

        int mid = (l + r) / 2;

        add(node * 2 + 1, l, mid, lf, rg, x);
        add(node * 2 + 2, mid, r, lf, rg, x);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void add(int l, int r, int x) {
        add(0, 0, size, l, r, x);
    }

    void rev(int node, int l, int r, int lf, int rg) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = r - l - val[node];
            if (lazy[node] == -1) lazy[node] = 2; else lazy[node] = 1 - lazy[node];
            return;
        }

        int mid = (l + r) / 2;

        rev(node * 2 + 1, l, mid, lf, rg);
        rev(node * 2 + 2, mid, r, lf, rg);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void rev(int l, int r) {
        rev(0, 0, size, l, r);
    }

    int get(int node, int l, int r) {

        propagate(node, l, r);
        if (val[node] == r - l) return -1;
        if (l == r - 1) {
            return l;
        }

        int mid = (l + r) / 2;
        int ans = get(node * 2 + 1, l, mid);
        if (ans == -1) ans = get(node * 2 + 2, mid, r);

        return ans;

    }

    int get() {
        return get(0, 0, size);
    }

};
int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;

    for(int i = 1; i <= n; i++) {
        ll op, x, y;
        cin >> op >> x >> y;
        q.pb(qr{op, x, y});
        vals.pb(x);
        vals.pb(y);
        vals.pb(y + 1);
    }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

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

        q[i - 1].l = lower_bound(vals.begin(), vals.end(), q[i - 1].l) - vals.begin();
        q[i - 1].r = lower_bound(vals.begin(), vals.end(), q[i - 1].r) - vals.begin();

    }

    Segment_Tree st;
    st.init(6 * n);

    for(auto it : q) {

        // cout << it.l << ' ' << it.r << '\n';

        if (it.o == 1) {
            st.add(it.l, it.r + 1, 1);
        } else if (it.o == 2) {
            st.add(it.l, it.r + 1, 0);
        } else if (it.o == 3) {
            st.rev(it.l, it.r + 1);
        }

        // cout << st.val[0] << '\n';
        //cout << st.get() << '\n';
        // cout << "ska\n";
        cout << vals[st.get()] << '\n';

    }
    return 0;
}

// 5
// 3 1 4
// 3 1 4
// 1 1 2
// 1 1 2
// 3 1 2

// 5
// 5
// 5
// 5
// 1


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef long double ld;
const int N = 100006;
const int nein = -1;

struct qr {
    int o, l, r;
};

map<int, int> h;
vector<int> vals;
vector<qr> q;

struct Segment_Tree {

    vector<int> val, lazy;
    int size;

    void init(int x) {
        size = 1;
        while(size < x) size *= 2;
        val.resize(size * 2);
        lazy.resize(size * 2);
    }

    void propagate(int node, int l, int r) {

        if (l == r - 1) {
            lazy[node] = nein;
            return;
        }

        if (lazy[node] == nein) {
            return;
        }

        int mid = (l + r) / 2;
        for(int x : {2 * node + 1, 2 * node + 2}) {

            if (lazy[node] < 2) val[x] = lazy[node] * (mid - l);
            else val[x] = mid - l - val[x];

            lazy[x] = lazy[node];
        }

        lazy[node] = nein;

    }
    int merge(int a, int b) {
        return a + b;
    }

    void add(int node, int l, int r, int lf, int rg, int x) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = x * (r - l);
            lazy[node] = x;
            return;
        }

        int mid = (l + r) / 2;

        add(node * 2 + 1, l, mid, lf, rg, x);
        add(node * 2 + 2, mid, r, lf, rg, x);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void add(int l, int r, int x) {
        add(0, 0, size, l, r, x);
    }

    void rev(int node, int l, int r, int lf, int rg) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = r - l - val[node];
            lazy[node] = 2;
            return;
        }

        int mid = (l + r) / 2;

        rev(node * 2 + 1, l, mid, lf, rg);
        rev(node * 2 + 2, mid, r, lf, rg);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void rev(int l, int r) {
        rev(0, 0, size, l, r);
    }

    int get(int node, int l, int r) {

        propagate(node, l, r);

        if (val[node] == r - l) return -1;

        if (l == r - 1) {
            return l;
        }

        int mid = (l + r) / 2;
        int ans = get(node * 2 + 1, l, mid);
        if (ans == -1) ans = get(node * 2 + 2, mid, r);

        return ans;

    }

    int get() {
        return get(0, 0, size);
    }

};
int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;

    for(int i = 1; i <= n; i++) {
        int op, x, y;
        cin >> op >> x >> y;
        q.pb(qr{op, x, y});
        vals.pb(x);
        vals.pb(y);
        vals.pb(y + 1);
    }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

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

        q[i - 1].l = lower_bound(vals.begin(), vals.end(), q[i - 1].l) - vals.begin();
        q[i - 1].r = lower_bound(vals.begin(), vals.end(), q[i - 1].r) - vals.begin();

    }

    Segment_Tree st;
    st.init(3 * n);

    for(auto it : q) {

        // cout << it.l << ' ' << it.r << '\n';

        if (it.o == 1) {
            st.add(it.l, it.r + 1, 1);
        } else if (it.o == 2) {
            st.add(it.l, it.r + 1, 0);
        } else if (it.o == 3) {
            st.rev(it.l, it.r + 1);
        }

        // cout << "ska\n";
        cout << vals[st.get()] << '\n';

    }
    return 0;
}


#include <bits/stdc++.h>
#define f first
#define s second
#define pb push_back
#define mp make_pair
using namespace std;
typedef unsigned int uint;
typedef long long ll;
typedef long double ld;
const int N = 100006;
const int nein = -1;

struct qr {
    int o, l, r;
};

vector<int> vals;
vector<qr> q;

struct Segment_Tree {

    vector<int> val, lazy;
    int size;

    void init(int x) {
        size = 1;
        while(size < x) size *= 2;
        val.resize(size * 2);
        lazy.resize(size * 2);
    }

    void propagate(int node, int l, int r) {

        if (l == r - 1) {
            lazy[node] = nein;
            return;
        }

        if (lazy[node] == nein) {
            return;
        }

        int mid = (l + r) / 2;
        for(int x : {2 * node + 1, 2 * node + 2}) {

            if (lazy[node] < 2) val[x] = lazy[node] * (mid - l), lazy[x] = lazy[node];
            else {
                if (lazy[node] == 2) val[x] = mid - l - val[x];
                if (lazy[x] < 2) lazy[x] = 2; else lazy[x] ^= 1;
            }

        }

        lazy[node] = nein;

    }
    int merge(int a, int b) {
        return a + b;
    }

    void add(int node, int l, int r, int lf, int rg, int x) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = x * (r - l);
            lazy[node] = x;
            return;
        }

        int mid = (l + r) / 2;

        add(node * 2 + 1, l, mid, lf, rg, x);
        add(node * 2 + 2, mid, r, lf, rg, x);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void add(int l, int r, int x) {
        add(0, 0, size, l, r, x);
    }

    void rev(int node, int l, int r, int lf, int rg) {

        propagate(node, l, r);

        if (r <= lf || l >= rg) return;

        if (l >= lf && r <= rg) {
            val[node] = r - l - val[node];
            if (lazy[node] < 2) lazy[node] = 2; else lazy[node] ^= 1;
            return;
        }

        int mid = (l + r) / 2;

        rev(node * 2 + 1, l, mid, lf, rg);
        rev(node * 2 + 2, mid, r, lf, rg);

        val[node] = merge(val[node * 2 + 1], val[node * 2 + 2]);

    }

    void rev(int l, int r) {
        rev(0, 0, size, l, r);
    }

    int get(int node, int l, int r) {

        propagate(node, l, r);
        if (val[node] == r - l) return -1;
        if (l == r - 1) {
            return l;
        }

        int mid = (l + r) / 2;
        int ans = get(node * 2 + 1, l, mid);
        if (ans == -1) ans = get(node * 2 + 2, mid, r);

        return ans;

    }

    int get() {
        return get(0, 0, size);
    }

};
int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;

    for(int i = 1; i <= n; i++) {
        int op, x, y;
        cin >> op >> x >> y;
        q.pb(qr{op, x, y});
        vals.pb(x);
        vals.pb(y);
        vals.pb(y + 1);
    }

    sort(vals.begin(), vals.end());
    vals.erase(unique(vals.begin(), vals.end()), vals.end());

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

        q[i - 1].l = lower_bound(vals.begin(), vals.end(), q[i - 1].l) - vals.begin();
        q[i - 1].r = lower_bound(vals.begin(), vals.end(), q[i - 1].r) - vals.begin();

    }

    Segment_Tree st;
    st.init(6 * n);

    for(auto it : q) {

        // cout << it.l << ' ' << it.r << '\n';

        if (it.o == 1) {
            st.add(it.l, it.r + 1, 1);
        } else if (it.o == 2) {
            st.add(it.l, it.r + 1, 0);
        } else if (it.o == 3) {
            st.rev(it.l, it.r + 1);
        }

        // cout << st.val[0] << '\n';
        //cout << st.get() << '\n';
        // cout << "ska\n";
        cout << vals[st.get()] << '\n';

    }
    return 0;
}

// 5
// 3 1 4
// 3 1 4
// 1 1 2
// 1 1 2
// 3 1 2

// 5
// 5
// 5
// 5
// 1