#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define M 1000000
using namespace std;

int a[M];

struct
{
    int from,to;
    int ans;
}tree[M];

void make_a_tree(int left,int right,int node)
{
    tree[node].from=left;
    tree[node].to=right;
    if(left==right)
    {
        tree[node].ans=a[left];
        return ;
    }
    int div;
    div=(left+right)/2;
    make_a_tree(left,div,node+node);
    make_a_tree(div+1,right,node+node+1);
    tree[node].ans=tree[node+node].ans&tree[node+node+1].ans;
    return ;
}

int query(int left,int right,int node)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        return tree[node].ans;
    }
    int div;
    int ans1,ans2;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        return query(left,right,node+node);
    }
    else if(left>div)
    {
        return query(left,right,node+node+1);
    }
    else
    {
        ans1=query(left,div,node+node);
        ans2=query(div+1,right,node+node+1);
        return ans1&ans2;
    }
}

main()
{
    int i,j,k,n,m;
    int x,y,val,start,fin,cnt,t,par;
    cin>>n>>m;
    fill(a,a+n+1,0);
    vector<pair<int,pair<int,int> > > v;
    set<pair<pair<int,int>,int> > s;
    set<pair<pair<int,int>,int> >::iterator it,it2;
    pair<pair<int,int>,int > ele,ele2;
    for(i=0;i<m;i++)
    {
        cin>>x>>y>>val;
        v.pb(mp(val,mp(x,y)));
        s.insert(mp(mp(x,y),val));
    }
    sort(v.begin(),v.end());

    while(!s.empty())
    {
    it=s.begin();
    ele=*it;
    start=ele.first.first;
    fin=ele.first.second;
    val=ele.second;
        it2=it;
        it2++;
        if(it2==s.end())
        {
            for(i=start-1;i<=fin-1;i++) a[i]=val;
            s.erase(ele);
        }
        else
        {
            ele2=*it2;
            if(ele2.first.first>fin)
            {
                for(i=start-1;i<=fin-1;i++) a[i]=val;
                s.erase(ele);
            }
            else if(ele2.second<=val)
            {
                if(ele2.first.second<=fin)
                {
                    s.erase(ele2);
                }
                else
                {
                    s.erase(ele2);
                    ele2.first.first=fin+1;
                    s.insert(ele2);
                }
            }
            else
            {
                if(fin<=ele2.first.second)
                {
                    for(i=start-1;i<ele2.first.first-1;i++) a[i]=val;
                    s.erase(ele);
                }
                else
                {
                    for(i=start-1;i<ele2.first.first-1;i++) a[i]=val;
                    s.erase(ele);
                    ele.first.first=ele2.first.second+1;
                    s.insert(ele);
                }
            }
        }
    }

    make_a_tree(0,n-1,1);

    for(i=0;i<v.size();i++)
    {
        par=query(v[i].second.first-1,v[i].second.second-1,1);
        if(par!=v[i].first)
        {
            cout<<"NO";
            return 0;
        }
    }

    cout<<"YES"<<endl;
    for(i=0;i<n;i++) cout<<a[i]<<" ";
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define M 1000000
using namespace std;

int a[M];

struct
{
    int from,to;
    int ans;
}tree[M];

void make_a_tree(int left,int right,int node)
{
    tree[node].from=left;
    tree[node].to=right;
    if(left==right)
    {
        tree[node].ans=a[left];
        return ;
    }
    int div;
    div=(left+right)/2;
    make_a_tree(left,div,node+node);
    make_a_tree(div+1,right,node+node+1);
    tree[node].ans=tree[node+node].ans&tree[node+node+1].ans;
    return ;
}

int query(int left,int right,int node)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        return tree[node].ans;
    }
    int div;
    int ans1,ans2;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        return query(left,right,node+node);
    }
    else if(left>div)
    {
        return query(left,right,node+node+1);
    }
    else
    {
        ans1=query(left,div,node+node);
        ans2=query(div+1,right,node+node+1);
        return ans1&ans2;
    }
}

main()
{
    int i,j,k,n,m;
    int x,y,val,start,fin,cnt,t,par;
    cin>>n>>m;
    fill(a,a+n+1,0);
    vector<pair<int,pair<int,int> > > v;
    set<pair<pair<int,int>,int> > s;
    set<pair<pair<int,int>,int> >::iterator it,it2;
    pair<pair<int,int>,int > ele,ele2;
    for(i=0;i<m;i++)
    {
        cin>>x>>y>>val;
        v.pb(mp(val,mp(x,y)));
        s.insert(mp(mp(x,y),val));
    }
    sort(v.begin(),v.end());

    while(!s.empty())
    {
    it=s.begin();
    ele=*it;
    start=ele.first.first;
    fin=ele.first.second;
    val=ele.second;
        it2=it;
        it2++;
        if(it2==s.end())
        {
            for(i=start-1;i<=fin-1;i++) a[i]=val;
            s.erase(ele);
        }
        else
        {
            ele2=*it2;
            if(ele2.first.first>start)
            {
                for(i=start-1;i<=fin-1;i++) a[i]=val;
                s.erase(ele);
            }
            else if(ele2.second<=val)
            {
                if(ele2.first.second<=fin)
                {
                    s.erase(ele2);
                }
                else
                {
                    s.erase(ele2);
                    ele2.first.first=fin+1;
                    s.insert(ele2);
                }
            }
            else
            {
                if(fin<=ele2.first.second)
                {
                    for(i=start-1;i<ele2.first.first-1;i++) a[i]=val;
                    s.erase(ele);
                }
                else
                {
                    for(i=start-1;i<ele2.first.first-1;i++) a[i]=val;
                    s.erase(ele);
                    ele.first.first=ele2.first.second+1;
                    s.insert(ele);
                }
            }
        }
    }

    make_a_tree(0,n-1,1);

    for(i=0;i<v.size();i++)
    {
        par=query(v[i].second.first-1,v[i].second.second-1,1);
        if(par!=v[i].first)
        {
            cout<<"NO";
            return 0;
        }
    }

    cout<<"YES"<<endl;
    for(i=0;i<n;i++) cout<<a[i]<<" ";
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define M 1000000
using namespace std;

struct
{
    int from,to,ans,sum;
}tree[M];

void make_a_tree(int left,int right,int node)
{
    tree[node].ans=0;
    tree[node].sum=0;
    tree[node].from=left;
    tree[node].to=right;
    if(left==right)
    {
        return ;
    }
    int div;
    div=(left+right)/2;
    make_a_tree(left,div,node+node);
    make_a_tree(div+1,right,node+node+1);
}

void update(int left,int right,int node,int val)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        tree[node].sum=tree[node].sum|val;
        tree[node].ans=tree[node].sum;
        if(left!=right)
        {
            tree[node].ans=tree[node].ans|(tree[node+node].ans&tree[node+node+1].ans);
        }
        return ;
    }
    int div;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        update(left,right,node+node,val);
    }
    else if(left>div)
    {
        update(left,right,node+node+1,val);
    }
    else
    {
        update(left,div,node+node,val);
        update(div+1,right,node+node+1,val);
    }
    tree[node].ans=tree[node].sum|(tree[node+node].ans&tree[node+node+1].ans);
}

int query(int left,int right,int node)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        return tree[node].ans;
    }
    int div;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        return tree[node].sum|query(left,right,node+node);
    }
    else if(left>div)
    {
        return tree[node].sum|query(left,right,node+node+1);
    }
    else
    {
        int ans1,ans2;
        ans1=query(left,div,node+node);
        ans2=query(div+1,right,node+node+1);
        return tree[node].sum|(ans1&ans2);
    }
}

main()
{
    int i,j,k,n,m,x,y,val,par;
    cin>>n>>m;
    vector<pair<int,pair<int,int> > > v;
    for(i=0;i<m;i++)
    {
        scanf("%d %d %d",&x,&y,&val);
        x--;
        y--;
        v.pb(mp(val,mp(x,y)));
    }
    sort(v.begin(),v.end());
    make_a_tree(0,n-1,1);
    for(i=0;i<v.size();i++)
    {
        update(v[i].second.first,v[i].second.second,1,v[i].first);
    }
    for(i=0;i<v.size();i++)
    {
        par=query(v[i].second.first,v[i].second.second,1);
        if(par!=v[i].first)
        {
            cout<<"NO";
            return 0;
        }
    }
    cout<<"YES"<<endl;
    for(i=0;i<n;i++)
    {
        cout<<query(i,i,1)<<" ";
    }
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define M 500000
using namespace std;

long long a[M];

struct
{
    int from,to;
    long long ans;
}tree[M];

void make_a_tree(int left,int right,int node)
{
    tree[node].from=left;
    tree[node].to=right;
    if(left==right)
    {
        tree[node].ans=a[left];
        return ;
    }
    int div;
    div=(left+right)/2;
    make_a_tree(left,div,node+node);
    make_a_tree(div+1,right,node+node+1);
    tree[node].ans=tree[node+node].ans&tree[node+node+1].ans;
    return ;
}

long long query(int left,int right,int node)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        return tree[node].ans;
    }
    int div;
    int ans1,ans2;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        return query(left,right,node+node);
    }
    else if(left>div)
    {
        return query(left,right,node+node+1);
    }
    else
    {
        ans1=query(left,div,node+node);
        ans2=query(div+1,right,node+node+1);
        return ans1&ans2;
    }
}

main()
{
    int i,j,k,n,m;
    long long x,y,val,start,fin,cnt,t,par;
    cin>>n>>m;
    int next[n+1];
    fill(a,a+n+1,0);
    for(i=0;i<=n;i++) next[i]=i+1;
    vector<pair<int,pair<int,int> > > v;
    for(i=0;i<m;i++)
    {
        cin>>x>>y>>val;
        v.pb(mp(val,mp(x,y)));
    }
    sort(v.begin(),v.end());
    for(i=v.size()-1;i>=0;i--)
    {
        start=v[i].second.first;
        fin=v[i].second.second;
        start--;
        fin--;
        val=v[i].first;
        while(start<=fin&&start<n)
        {
            if(a[start]<val)
            {
                a[start]=val;
                t=next[start];
                next[start]=next[fin];
                start++;
            }
            else if(a[start]==val)
            {
                start=next[start];
            }
            else
            {
                start=next[start];
            }
        }
    }

    make_a_tree(0,n-1,1);

    for(i=0;i<v.size();i++)
    {
        par=query(v[i].second.first-1,v[i].second.second-1,1);
        if(par!=v[i].first)
        {
            cout<<"NO";
            return 0;
        }
    }

    cout<<"YES"<<endl;
    for(i=0;i<n;i++) cout<<a[i]<<" ";
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define M 1000000
using namespace std;

struct
{
    int from,to,ans,sum;
}tree[M];

void make_a_tree(int left,int right,int node)
{
    tree[node].ans=0;
    tree[node].sum=0;
    tree[node].from=left;
    tree[node].to=right;
    if(left==right)
    {
        return ;
    }
    int div;
    div=(left+right)/2;
    make_a_tree(left,div,node+node);
    make_a_tree(div+1,right,node+node+1);
}

void update(int left,int right,int node,int val)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        tree[node].sum=tree[node].sum|val;
        tree[node].ans=tree[node].sum;
        if(left!=right)
        {
            tree[node].ans=tree[node].ans|(tree[node+node].ans&tree[node+node+1].ans);
        }
        return ;
    }
    int div;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        update(left,right,node+node,val);
    }
    else if(left>div)
    {
        update(left,right,node+node+1,val);
    }
    else
    {
        update(left,div,node+node,val);
        update(div+1,right,node+node+1,val);
    }
    tree[node].ans=tree[node].sum|(tree[node+node].ans&tree[node+node+1].ans);
}

int query(int left,int right,int node)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        return tree[node].ans;
    }
    int div;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        return tree[node].sum|query(left,right,node+node);
    }
    else if(left>div)
    {
        return tree[node].sum|query(left,right,node+node+1);
    }
    else
    {
        int ans1,ans2;
        ans1=query(left,div,node+node);
        ans2=query(div+1,right,node+node+1);
        return tree[node].sum|(ans1&ans2);
    }
}

main()
{
    int i,j,k,n,m,x,y,val,par;
    cin>>n>>m;
    vector<pair<int,pair<int,int> > > v;
    for(i=0;i<m;i++)
    {
        scanf("%d %d %d",&x,&y,&val);
        x--;
        y--;
        v.pb(mp(val,mp(x,y)));
    }
    sort(v.begin(),v.end());
    make_a_tree(0,n-1,1);
    for(i=0;i<v.size();i++)
    {
        update(v[i].second.first,v[i].second.second,1,v[i].first);
    }
    for(i=v.size()-1;i>=0;i--)
    {
        par=query(v[i].second.first,v[i].second.second,1);
        if(par!=v[i].first)
        {
            cout<<"NO";
            return 0;
        }
    }
    cout<<"YES"<<endl;
    for(i=0;i<n;i++)
    {
        cout<<query(i,i,1)<<" ";
    }
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
using namespace std;
main()
{
    int i,j,k,n,m,x,y,val,start,fin,cnt,t;
    cin>>n>>m;
    int a[n+1],next[n+1];
    fill(a,a+n+1,0);
    for(i=0;i<=n;i++) next[i]=i+1;
    vector<pair<int,pair<int,int> > > v;
    for(i=0;i<m;i++)
    {
        scanf("%d %d %d",&x,&y,&val);
        v.pb(mp(val,mp(x,y)));
    }
    sort(v.begin(),v.end());
    for(i=v.size()-1;i>=0;i--)
    {
        start=v[i].second.first;
        fin=v[i].second.second;
        start--;
        fin--;
        val=v[i].first;
        cnt=0;
        while(start<=fin&&start<n)
        {
            if(a[start]<val)
            {
                a[start]=val;
                t=next[start];
                next[start]=next[fin];
                cnt++;
                start=t;
            }
            else if(a[start]==val)
            {
                cnt++;
                start=next[start];
            }
            else
            {
                if((val&a[start])!=val)
                {
                    cout<<"NO";
                    return 0;
                }
                start=next[start];
            }
        }
        if(cnt==0)
        {
            cout<<"NO";
            return 0;
        }
    }
    cout<<"YES"<<endl;
    for(i=0;i<n;i++) cout<<a[i]<<" ";
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define M 1000000
using namespace std;

int a[M];

struct
{
    int from,to;
    int ans;
}tree[M];

void make_a_tree(int left,int right,int node)
{
    tree[node].from=left;
    tree[node].to=right;
    if(left==right)
    {
        tree[node].ans=a[left];
        return ;
    }
    int div;
    div=(left+right)/2;
    make_a_tree(left,div,node+node);
    make_a_tree(div+1,right,node+node+1);
    tree[node].ans=tree[node+node].ans&tree[node+node+1].ans;
    return ;
}

int query(int left,int right,int node)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        return tree[node].ans;
    }
    int div;
    int ans1,ans2;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        return query(left,right,node+node);
    }
    else if(left>div)
    {
        return query(left,right,node+node+1);
    }
    else
    {
        ans1=query(left,div,node+node);
        ans2=query(div+1,right,node+node+1);
        return ans1&ans2;
    }
}

main()
{
    int i,j,k,n,m;
    int x,y,val,start,fin,cnt,t,par;
    cin>>n>>m;
    fill(a,a+n+1,0);
    vector<pair<int,pair<int,int> > > v;
    set<pair<pair<int,int>,int> > s;
    set<pair<pair<int,int>,int> >::iterator it,it2;
    pair<pair<int,int>,int > ele,ele2;
    for(i=0;i<m;i++)
    {
        cin>>x>>y>>val;
        v.pb(mp(val,mp(x,y)));
        s.insert(mp(mp(x,y),val));
    }
    sort(v.begin(),v.end());

    while(!s.empty())
    {
    it=s.begin();
    ele=*it;
    start=ele.first.first;
    fin=ele.first.second;
    val=ele.second;
        it2=it;
        it2++;
        if(it2==s.end())
        {
            for(i=start-1;i<=fin-1;i++) a[i]=val;
            s.erase(ele);
        }
        else
        {
            ele2=*it2;
            if(ele2.first.first>start)
            {
                for(i=start-1;i<=fin-1;i++) a[i]=val;
                s.erase(ele);
            }
            else if(ele2.second<val)
            {
                if(ele2.first.second<=fin)
                {
                    s.erase(ele2);
                }
                else
                {
                    s.erase(ele2);
                    ele2.first.first=fin+1;
                    s.insert(ele2);
                }
            }
            else
            {
                if(fin<=ele2.first.second)
                {
                    for(i=start-1;i<ele2.first.first-1;i++) a[i]=val;
                    s.erase(ele);
                }
                else
                {
                    for(i=start-1;i<ele2.first.first-1;i++) a[i]=val;
                    s.erase(ele);
                    ele.first.first=ele2.first.second+1;
                    s.insert(ele);
                }
            }
        }
    }

    make_a_tree(0,n-1,1);

    for(i=0;i<v.size();i++)
    {
        par=query(v[i].second.first-1,v[i].second.second-1,1);
        if(par!=v[i].first)
        {
            cout<<"NO";
            return 0;
        }
    }

    cout<<"YES"<<endl;
    for(i=0;i<n;i++) cout<<a[i]<<" ";
}


#include<iostream>
#include<cstdio>
#include<vector>
#include<set>
#include<algorithm>
#define pb push_back
#define mp make_pair
#define M 1000
using namespace std;

int a[M];

struct
{
    int from,to,ans;
}tree[M];

void make_a_tree(int left,int right,int node)
{
    tree[node].from=left;
    tree[node].to=right;
    if(left==right)
    {
        tree[node].ans=a[left];
        return ;
    }
    int div;
    div=(left+right)/2;
    make_a_tree(left,div,node+node);
    make_a_tree(div+1,right,node+node+1);
    tree[node].ans=tree[node+node].ans&tree[node+node+1].ans;
    return ;
}

int query(int left,int right,int node)
{
    if(tree[node].from==left&&tree[node].to==right)
    {
        return tree[node].ans;
    }
    int div;
    int ans1,ans2;
    div=(tree[node].from+tree[node].to)/2;
    if(right<=div)
    {
        return query(left,right,node+node);
    }
    else if(left>div)
    {
        return query(left,right,node+node+1);
    }
    else
    {
        ans1=query(left,div,node+node);
        ans2=query(div+1,right,node+node+1);
        return ans1&ans2;
    }
}

main()
{
    int i,j,k,n,m,x,y,val,start,fin,cnt,t,par;
    cin>>n>>m;
    int next[n+1];
    fill(a,a+n+1,0);
    for(i=0;i<=n;i++) next[i]=i+1;
    vector<pair<int,pair<int,int> > > v;
    for(i=0;i<m;i++)
    {
        scanf("%d %d %d",&x,&y,&val);
        v.pb(mp(val,mp(x,y)));
    }
    sort(v.begin(),v.end());
    for(i=v.size()-1;i>=0;i--)
    {
        start=v[i].second.first;
        fin=v[i].second.second;
        start--;
        fin--;
        val=v[i].first;
        while(start<=fin&&start<n)
        {
            if(a[start]<val)
            {
                a[start]=val;
                t=next[start];
                next[start]=next[fin];
                start++;
            }
            else if(a[start]==val)
            {
                start=next[start];
            }
            else
            {
                start=next[start];
            }
        }
    }

    make_a_tree(0,n-1,1);

    for(i=0;i<v.size();i++)
    {
        par=query(v[i].second.first-1,v[i].second.second-1,1);
        if(par!=v[i].first)
        {
            cout<<"NO";
            return 0;
        }
    }

    cout<<"YES"<<endl;
    for(i=0;i<n;i++) cout<<a[i]<<" ";
}


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

typedef long long LL;

#define PII       pair<int,int>
#define all(c)    c.begin(),c.end()
#define sz(c)     (int)c.size()
#define clr(c)    c.clear()
#define pb        push_back
#define mp        make_pair
#define cin(x)     scanf("%d",&x)
#define MOD       1000000007
#define EPS       1E-10

int segtree[1000000] = {0};
int arr[100001] = {0};

void buildTree(int l,int r,int pos)
{
    if(l == r)
    {
        segtree[pos] = arr[l-1];
        return ;
    }
    int mid = (l + r) / 2;
    buildTree(l , mid , 2 * pos);
    buildTree(mid + 1 , r , 2 * pos + 1);
    segtree[pos] = segtree[2*pos]&segtree[2*pos+1];
}

int query(int lQ,int rQ,int l,int r,int pos)
{
    if(l > rQ or r < lQ or l > r) return (1<<30)-1;
    if(l >= lQ && r <= rQ) return segtree[pos];
    int mid = (l + r) / 2;
    int A = query(lQ,rQ,l,mid,2*pos);
    int B = query(lQ,rQ,mid+1,r,2*pos+1);
    return (A&B);
}

int L[1000000] , R[1000000] , Q[1000000];

int st[31][100001] = {0};

int main()
{
    int n , m;
    cin(n);
    cin(m);
    for(int i = 0; i < m; i++)
    {
        cin(L[i]);
        cin(R[i]);
        cin(Q[i]);
        for(int j = 0; j < 30; j++)
            if(Q[i]&(1<<j))
            {
                st[j][L[i]-1] += 1;
                st[j][R[i]] += -1;
            }
    }
    for(int j = 0; j < 30; j++)
    {
        int s = 0;
        for(int i = 0; i < n; i++)
        {
            s += st[j][i];
            if(s)
                arr[i] |= (1<<j);
        }
    }
    buildTree(1,n,1);
    int poss = 1;
    for(int i = 0; i < m; i++)
    {
        int val = query(L[i] , R[i] , 1 , n , 1);
        if(val != Q[i])
        {
            printf("NO\n");
            return 0;
        }
    }

    //asda
    {
        printf("YES\n");
        for(int i = 0; i < n; i++)
            printf("%d ", arr[i]);
    }
      return 0;
}


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

typedef long long LL;

#define PII       pair<int,int>
#define all(c)    c.begin(),c.end()
#define sz(c)     (int)c.size()
#define clr(c)    c.clear()
#define pb        push_back
#define mp        make_pair
#define cin(x)     scanf("%d",&x)
#define MOD       1000000007
#define EPS       1E-10

int segtree[40][500000] = {0};
int lazy[40][500000] = {0};

void lazyUpdate(int l,int r,int pos,int idx)
{
    if(lazy[idx][pos] == 0) return ;
    segtree[idx][pos] = 1;
    if(l != r)
    {
        lazy[idx][2*pos] = lazy[idx][2*pos+1] = 1;
    }
    lazy[idx][pos] = 0;
}

void update(int lQ,int rQ,int l,int r,int pos,int idx)
{
    lazyUpdate(l,r,pos,idx);
    if(l > rQ or r < lQ or l > r) return ;
    else if(l >= lQ && r <= rQ)
    {
        segtree[idx][pos] = 1;
        if(l != r)
        {
            lazy[idx][2*pos] = lazy[idx][2*pos+1] = 1;
        }
        return ;
    }
    int mid = (l + r) / 2;
    update(lQ,rQ,l,mid,2*pos,idx);
    update(lQ,rQ,mid+1,r,2*pos+1,idx);
    segtree[idx][pos] = segtree[idx][2*pos]&segtree[idx][2*pos+1];
}

int query(int lQ,int rQ,int l,int r,int pos,int idx)
{
    lazyUpdate(l,r,pos,idx);
    if(l > rQ or r < lQ or l > r) return 1;
    if(l >= lQ && r <= rQ) return segtree[idx][pos];
    int mid = (l + r) / 2;
    int L = query(lQ,rQ,l,mid,2*pos,idx);
    int R = query(lQ,rQ,mid+1,r,2*pos+1,idx);
    return (L&R);
}

int main()
{
    int n , m;
    cin(n);
    cin(m);
    vector< pair<PII,int> > arr(m);
    for(int i = 0; i < m; i++)
    {
        cin(arr[i].first.first);
        cin(arr[i].first.second);
        cin(arr[i].second);
        for(int j = 0; j < 30; j++)
            if(arr[i].second&(1<<j))
                update(arr[i].first.first , arr[i].first.second , 1 , n , 1 , j);
    }
    int poss = 1;
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < 30; j++)
        {
            int f = arr[i].second & (1<<j);
            if(f) f = 1;
            int q = query(arr[i].first.first,  arr[i].first.second , 1 , n , 1 , j);
            if(f != q)
                poss = 0;
        }
    }
    if(poss)
    {
        printf("YES\n");
        for(int i = 0; i < n; i++)
        {
            int ans = 0;
            for(int j = 0; j < 30; j++)
            {
                int q = query(i + 1 , i + 1 , 1 , n , 1 , j);
                if(q)
                    ans += (1<<j);
            }
            printf("%d ", ans);
        }
    }
    else
        printf("NO\n");
      return 0;
}


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

typedef long long LL;

#define PII       pair<int,int>
#define all(c)    c.begin(),c.end()
#define sz(c)     (int)c.size()
#define clr(c)    c.clear()
#define pb        push_back
#define mp        make_pair
#define cin(x)     scanf("%d",&x)
#define MOD       1000000007
#define EPS       1E-10

int segtree[1000000] = {0};
int arr[100001] = {0};

void buildTree(int l,int r,int pos)
{
    if(l == r)
    {
        segtree[pos] = arr[l-1];
        return ;
    }
    int mid = (l + r) / 2;
    buildTree(l , mid , 2 * pos);
    buildTree(mid + 1 , r , 2 * pos + 1);
    segtree[pos] = segtree[2*pos]&segtree[2*pos+1];
}

int query(int lQ,int rQ,int l,int r,int pos)
{
    if(l > rQ or r < lQ or l > r) return (1<<30)-1;
    if(l >= lQ && r <= rQ) return segtree[pos];
    int mid = (l + r) / 2;
    int A = query(lQ,rQ,l,mid,2*pos);
    int B = query(lQ,rQ,mid+1,r,2*pos+1);
    return (A&B);
}

int L[1000000] , R[1000000] , Q[1000000];

int st[31][100001] = {0};

int main()
{
    int n , m;
    cin(n);
    cin(m);
    for(int i = 0; i < m; i++)
    {
        cin(L[i]);
        cin(R[i]);
        cin(Q[i]);
        for(int j = 0; j < 30; j++)
            if(Q[i]&(1<<j))
            {
                st[j][L[i]] = 1;
                st[j][R[i]] = -1;
            }
    }
    for(int j = 0; j < 30; j++)
    {
        int s = 0;
        for(int i = 0; i < n; i++)
        {
            s += st[i][j];
            if(s)
                arr[j] |= (1<<j);
        }
    }
    buildTree(1,n,1);
    int poss = 1;
    for(int i = 0; i < m; i++)
    {
        int val = query(L[i] , R[i] , 1 , n , 1);
        if(val != Q[i])
        {
            printf("NO\n");
            return 0;
        }
    }

    //asda
    {
        printf("YES\n");
        for(int i = 0; i < n; i++)
            printf("%d ", arr[i]);
    }
      return 0;
}


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

typedef long long LL;

#define PII       pair<int,int>
#define all(c)    c.begin(),c.end()
#define sz(c)     (int)c.size()
#define clr(c)    c.clear()
#define pb        push_back
#define mp        make_pair
#define cin(x)     scanf("%d",&x)
#define MOD       1000000007
#define EPS       1E-10

int segtree[1000000] = {0};
int arr[100001] = {0};

void buildTree(int l,int r,int pos)
{
    if(l == r)
    {
        segtree[pos] = arr[l-1];
        return ;
    }
    int mid = (l + r) / 2;
    buildTree(l , mid , 2 * pos);
    buildTree(mid + 1 , r , 2 * pos + 1);
    segtree[pos] = segtree[2*pos]&segtree[2*pos+1];
}

int query(int lQ,int rQ,int l,int r,int pos)
{
    if(l > rQ or r < lQ or l > r) return (1<<30)-1;
    if(l >= lQ && r <= rQ) return segtree[pos];
    int mid = (l + r) / 2;
    int A = query(lQ,rQ,l,mid,2*pos);
    int B = query(lQ,rQ,mid+1,r,2*pos+1);
    return (A&B);
}

int L[1000000] , R[1000000] , Q[1000000];

int add[1000000] = {0};
int rem[1000000] = {0};

int main()
{
    int n , m;
    cin(n);
    cin(m);
    for(int i = 0; i < m; i++)
    {
        cin(L[i]);
        cin(R[i]);
        cin(Q[i]);
        for(int j = 0; j < 30; j++)
            if(Q[i]&(1<<j))
            {
                add[L[i] - 1] |= (1<<j);
                rem[R[i]] |= (1<<j);
            }
    }
    int sum = 0;
    for(int i = 0; i < n; i++)
    {
        sum += add[i] - rem[i];
        arr[i] = sum;
    }
    buildTree(1,n,1);
    int poss = 1;
    for(int i = 0; i < m; i++)
    {
        int val = query(L[i] , R[i] , 1 , n , 1);
        if(val != Q[i])
        {
            printf("NO\n");
            return 0;
        }
    }

    //asda
    {
        printf("YES\n");
        for(int i = 0; i < n; i++)
            printf("%d ", arr[i]);
    }
      return 0;
}


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

typedef long long LL;

#define PII       pair<int,int>
#define all(c)    c.begin(),c.end()
#define sz(c)     (int)c.size()
#define clr(c)    c.clear()
#define pb        push_back
#define mp        make_pair
#define cin(x)     scanf("%d",&x)
#define MOD       1000000007
#define EPS       1E-10

int segtree[1000000] = {0};
int arr[100001] = {0};

void buildTree(int l,int r,int pos)
{
    if(l == r)
    {
        segtree[pos] = arr[l-1];
        return ;
    }
    int mid = (l + r) / 2;
    buildTree(l , mid , 2 * pos);
    buildTree(mid + 1 , r , 2 * pos + 1);
    segtree[pos] = segtree[2*pos]&segtree[2*pos+1];
}

int query(int lQ,int rQ,int l,int r,int pos)
{
    if(l > rQ or r < lQ or l > r) return 1;
    if(l >= lQ && r <= rQ) return segtree[pos];
    int mid = (l + r) / 2;
    int A = query(lQ,rQ,l,mid,2*pos);
    int B = query(lQ,rQ,mid+1,r,2*pos+1);
    return (A&B);
}

int L[1000000] , R[1000000] , Q[1000000];

int main()
{
    int n , m;
    cin(n);
    cin(m);
    for(int i = 0; i < m; i++)
    {
        cin(L[i]);
        cin(R[i]);
        cin(Q[i]);
        for(int j = 0; j < 30; j++)
            if(Q[i]&(1<<j))
            {
                arr[L[i] - 1] += (1<<j);
                arr[R[i]] -= (1<<j);
            }
    }
    int sum = 0;
    for(int i = 0; i < n; i++)
    {
        sum += arr[i];
        arr[i] = sum;
    }
    buildTree(1,n,1);
    int poss = 1;
    for(int i = 0; i < m; i++)
    {
        int val = query(L[i] , R[i] , 1 , n , 1);
        if(val != Q[i])
        {
            printf("NO\n");
            return 0;
        }
    }

    //asda
    {
        printf("YES\n");
        for(int i = 0; i < n; i++)
            printf("%d ", arr[i]);
    }
      return 0;
}


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

typedef long long LL;

#define PII       pair<int,int>
#define all(c)    c.begin(),c.end()
#define sz(c)     (int)c.size()
#define clr(c)    c.clear()
#define pb        push_back
#define mp        make_pair
#define cin(x)     scanf("%d",&x)
#define MOD       1000000007
#define EPS       1E-10

int segtree[1000000] = {0};
int arr[100001] = {0};

void buildTree(int l,int r,int pos)
{
    if(l == r)
    {
        segtree[pos] = arr[l-1];
        return ;
    }
    int mid = (l + r) / 2;
    buildTree(l , mid , 2 * pos);
    buildTree(mid + 1 , r , 2 * pos + 1);
    segtree[pos] = segtree[2*pos]&segtree[2*pos+1];
}

int query(int lQ,int rQ,int l,int r,int pos)
{
    if(l > rQ or r < lQ or l > r) return (1<<30)-1;
    if(l >= lQ && r <= rQ) return segtree[pos];
    int mid = (l + r) / 2;
    int A = query(lQ,rQ,l,mid,2*pos);
    int B = query(lQ,rQ,mid+1,r,2*pos+1);
    return (A&B);
}

int L[1000000] , R[1000000] , Q[1000000];

int st[31][100001] = {0};

int main()
{
    int n , m;
    cin(n);
    cin(m);
    for(int i = 0; i < m; i++)
    {
        cin(L[i]);
        cin(R[i]);
        cin(Q[i]);
        for(int j = 0; j < 30; j++)
            if(Q[i]&(1<<j))
            {
                st[j][L[i]-1] = 1;
                st[j][R[i]] = -1;
            }
    }
    for(int j = 0; j < 30; j++)
    {
        int s = 0;
        for(int i = 0; i < n; i++)
        {
            s += st[j][i];
            if(s)
                arr[i] |= (1<<j);
        }
    }
    buildTree(1,n,1);
    int poss = 1;
    for(int i = 0; i < m; i++)
    {
        int val = query(L[i] , R[i] , 1 , n , 1);
        if(val != Q[i])
        {
            printf("NO\n");
            return 0;
        }
    }

    //asda
    {
        printf("YES\n");
        for(int i = 0; i < n; i++)
            printf("%d ", arr[i]);
    }
      return 0;
}


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

typedef long long LL;

#define PII       pair<int,int>
#define all(c)    c.begin(),c.end()
#define sz(c)     (int)c.size()
#define clr(c)    c.clear()
#define pb        push_back
#define mp        make_pair
#define cin(x)     scanf("%d",&x)
#define MOD       1000000007
#define EPS       1E-10

int segtree[40][500000] = {0};
int lazy[40][500000] = {0};

void lazyUpdate(int l,int r,int pos,int idx)
{
    if(lazy[idx][pos] == 0) return ;
    segtree[idx][pos] = 1;
    if(l != r)
    {
        lazy[idx][2*pos] = lazy[idx][2*pos+1] = 1;
    }
    lazy[idx][pos] = 0;
}

void update(int lQ,int rQ,int l,int r,int pos,int idx)
{
    lazyUpdate(l,r,pos,idx);
    if(l > rQ or r < lQ or l > r) return ;
    else if(l >= lQ && r <= rQ)
    {
        segtree[idx][pos] = 1;
        if(l != r)
        {
            lazy[idx][2*pos] = lazy[idx][2*pos+1] = 1;
        }
        return ;
    }
    int mid = (l + r) / 2;
    update(lQ,rQ,l,mid,2*pos,idx);
    update(lQ,rQ,mid+1,r,2*pos+1,idx);
    segtree[idx][pos] = segtree[idx][2*pos]&segtree[idx][2*pos+1];
}

int query(int lQ,int rQ,int l,int r,int pos,int idx)
{
    lazyUpdate(l,r,pos,idx);
    if(l > rQ or r < lQ or l > r) return 1;
    if(l >= lQ && r <= rQ) return segtree[idx][pos];
    int mid = (l + r) / 2;
    int L = query(lQ,rQ,l,mid,2*pos,idx);
    int R = query(lQ,rQ,mid+1,r,2*pos+1,idx);
    return (L&R);
}

int L[1000000] , R[1000000] , Q[1000000];

int main()
{
    int n , m;
    cin(n);
    cin(m);
    for(int i = 0; i < m; i++)
    {
        cin(L[i]);
        cin(R[i]);
        cin(Q[i]);
        for(int j = 0; j < 30; j++)
            if(Q[i]&(1<<j))
                update(L[i] , R[i] , 1 , n , 1 , j);
    }
    int poss = 1;
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < 30; j++)
        {
            int f = Q[i] & (1<<j);
            if(f) continue;
            int q = query(L[i],  R[i] , 1 , n , 1 , j);
            poss = !q;
            if(!poss) break;
        }
        if(!poss) break;
    }
    if(poss)
    {
        printf("YES\n");
        for(int i = 0; i < n; i++)
        {
            int ans = 0;
            for(int j = 0; j < 30; j++)
            {
                int q = query(i + 1 , i + 1 , 1 , n , 1 , j);
                if(q)
                    ans += (1<<j);
            }
            printf("%d ", ans);
        }
    }
    else
        printf("NO\n");
      return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MAX 100000
using namespace std;

int l[100010],r[100010],q[100010],lazy[5*MAX]={0},t[5*MAX]={0};

void update(long long v,long long b,long long e,long long x,long long y,long long val)
{
    //cout << v << " "<<b <<" "<<e<<" "<<x<<" "<<y<<" "<<val<<endl;
    if(lazy[v]!=0)
    {
        t[v]|=lazy[v];
        if(b!=e){
        lazy[2*v+1]|=lazy[v];
        lazy[2*v+2] |= lazy[v];
        }
        lazy[v] = 0;
    }
    if(x>y) return ;        //

    if(x<=b && e<=y)
    {
        //printf("b=%d e=%d x=%d y=%d\n",b,e,x,y);
        t[v]|=val;
        if(b!=e)
        {
            lazy[2*v+1]|= val;
            lazy[2*v+2] |= val;
        }

        return ;
    }

    long long mid = (b+e)>>1;
    update(2*v+1,b,mid,x,min(mid,y),val);
    update(2*v+2,mid+1,e,max(mid+1,x),y,val);
    t[v] = t[2*v+1] & t[2*v+2];

    return ;
}

long long query(long long v,long long b,long long e,long long x,long long y)
{
    long long i,val = ((long long)1<<30)-1;
    if(lazy[v]!=0)
        {
            t[v]|=lazy[v];
            if(b!=e){
            lazy[2*v+1]|=lazy[v];
            lazy[2*v+2] |= lazy[v];
            }
            lazy[v] = 0;
        }

    if(x>y){

        return val;
    }

    if(x<=b && e<=y) return t[v];
    long long mid = (b+e)>>1;

    long long q1 = query(2*v+1,b,mid,x,min(mid,y));
    long long q2 = query(2*v+2,mid+1,e,max(mid+1,x),y);

    return (q1&q2);
}

int main()
{
    int i,j,k,n,m,flag=1;
    scanf("%d%d",&n,&m);

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
        r[i]--;
        update(0,0,n-1,l[i],r[i],q[i]);
    }

    for(i=0;i<m;i++)
    {
        //cout <<l[i]<<" "<<r[i]<<endl;
        //cout << query(0,0,n-1,l[i],r[i]) <<endl;
        if(query(0,0,n-1,l[i],r[i])!=q[i])
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        printf("YES\n");
        for(i=0;i<n;i++)
            cout << query(0,0,n-1,i,i) <<" ";
        printf("\n");
    }
    else
        printf("NO\n");
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MAX 100000
using namespace std;

int l[100010],r[100010],q[100010],lazy[5*MAX]={0},t[5*MAX]={0};

void update(long long v,long long b,long long e,long long x,long long y,long long val)
{
    //cout << v << " "<<b <<" "<<e<<" "<<x<<" "<<y<<" "<<val<<endl;
    if(lazy[v]!=0)
    {
        t[v]|=lazy[v];
        if(b!=e){
        lazy[2*v+1]|=lazy[v];
        lazy[2*v+2] |= lazy[v];
        }
        lazy[v] = 0;
    }
    if(x>y) return ;        //

    if(x==b && e==y)
    {
        //printf("b=%d e=%d x=%d y=%d\n",b,e,x,y);
        t[v]|=val;
        if(b!=e)
        {
            lazy[2*v+1]|= val;
            lazy[2*v+2] |= val;
        }

        return ;
    }

    long long mid = (b+e)>>1;
    update(2*v+1,b,mid,x,min(mid,y),val);
    update(2*v+2,mid+1,e,max(mid+1,x),y,val);
    t[v] = t[2*v+1] & t[2*v+2];

    return ;
}

long long query(long long v,long long b,long long e,long long x,long long y)
{
    long long i,val = ((long long)1<<30)-1;
    if(lazy[v]!=0)
        {
            t[v]|=lazy[v];
            if(b!=e){
            lazy[2*v+1]|=lazy[v];
            lazy[2*v+2] |= lazy[v];
            }
            lazy[v] = 0;
        }

    if(x>y){

        return val;
    }

    if(x==b && e==y) return t[v];
    long long mid = (b+e)>>1;

    long long q1 = query(2*v+1,b,mid,x,min(mid,y));
    long long q2 = query(2*v+2,mid+1,e,max(mid+1,x),y);

    return (q1&q2);
}

int main()
{
    int i,j,k,n,m,flag=1;
    scanf("%d%d",&n,&m);

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
        r[i]--;
        update(0,0,n-1,l[i],r[i],q[i]);
    }

    for(i=0;i<m;i++)
    {
        //cout <<l[i]<<" "<<r[i]<<endl;
        //cout << query(0,0,n-1,l[i],r[i]) <<endl;
        if(query(0,0,n-1,l[i],r[i])!=q[i])
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        printf("YES\n");
        for(i=0;i<n;i++)
            cout << query(0,0,n-1,i,i) <<" ";
        printf("\n");
    }
    else
        printf("NO\n");
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MAX 100000
using namespace std;

int a[100010],l[100010],r[100010],q[100010],lazy[100010]={0},t[5*MAX]={0};

void update(long long v,long long b,long long e,long long x,long long y,long long val)
{
    //cout << v << " "<<b <<" "<<e<<" "<<x<<" "<<y<<" "<<val<<endl;
    if(lazy[v]!=0)
    {
        t[v]|=lazy[v];
        if(b!=e){
        lazy[2*v+1]|=lazy[v];
        lazy[2*v+2] |= lazy[v];
        }
        lazy[v] = 0;
    }
    if(x>y) return ;        //

    if(x<=b && e<=y)
    {
        //printf("b=%d e=%d x=%d y=%d\n",b,e,x,y);
        t[v]|=val;
        if(b!=e)
        {
            lazy[2*v+1]|= val;
            lazy[2*v+2] |= val;
        }

        return ;
    }

    long long mid = (b+e)>>1;
    update(2*v+1,b,mid,x,min(mid,y),val);
    update(2*v+2,mid+1,e,max(mid+1,x),y,val);
    t[v] = t[2*v+1] & t[2*v+2];

    return ;
}

long long query(long long v,long long b,long long e,long long x,long long y)
{
    long long i,val = ((long long)1<<30)-1;
    if(lazy[v]!=0)
        {
            t[v]|=lazy[v];
            if(b!=e){
            lazy[2*v+1]|=lazy[v];
            lazy[2*v+2] |= lazy[v];
            }
            lazy[v] = 0;
        }

    if(x>y){

        return val;
    }

    if(x<=b && e<=y) return t[v];
    long long mid = (b+e)>>1;

    long long q1 = query(2*v+1,b,mid,x,min(mid,y));
    long long q2 = query(2*v+2,mid+1,e,max(mid+1,x),y);

    return (q1&q2);
}

int main()
{
    int i,j,k,n,m,flag=1;
    scanf("%d%d",&n,&m);

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
        r[i]--;
        update(0,0,n-1,l[i],r[i],q[i]);
    }

    for(i=0;i<m;i++)
    {
        //cout <<l[i]<<" "<<r[i]<<endl;
        //cout << query(0,0,n-1,l[i],r[i]) <<endl;
        if(query(0,0,n-1,l[i],r[i])!=q[i])
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        printf("YES\n");
        for(i=0;i<n;i++)
            cout << query(0,0,n-1,i,i) <<" ";
        printf("\n");
    }
    else
        printf("NO\n");
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MAX 100000
using namespace std;

int a[100010],l[100010],r[100010],q[100010],lazy[100010]={0},t[5*MAX]={0};

void update(long long v,long long b,long long e,long long x,long long y,long long val)
{
    //cout << v << " "<<b <<" "<<e<<" "<<x<<" "<<y<<" "<<val<<endl;
    if(lazy[v]!=0)
    {
        t[v]|=lazy[v];
        if(b!=e){
        lazy[2*v+1]|=lazy[v];
        lazy[2*v+2] |= lazy[v];
        }
        lazy[v] = 0;
    }
    if(x>y) return ;        //

    if(x==b && e==y)
    {
        //printf("b=%d e=%d x=%d y=%d\n",b,e,x,y);
        t[v]|=val;
        if(b!=e)
        {
            lazy[2*v+1]|= val;
            lazy[2*v+2] |= val;
        }

        return ;
    }

    long long mid = (b+e)>>1;
    update(2*v+1,b,mid,x,min(mid,y),val);
    update(2*v+2,mid+1,e,max(mid+1,x),y,val);
    t[v] = t[2*v+1] & t[2*v+2];

    return ;
}

long long query(long long v,long long b,long long e,long long x,long long y)
{
    long long i,val = ((long long)1<<30)-1;
    if(lazy[v]!=0)
        {
            t[v]|=lazy[v];
            if(b!=e){
            lazy[2*v+1]|=lazy[v];
            lazy[2*v+2] |= lazy[v];
            }
            lazy[v] = 0;
        }

    if(x>y){

        return val;
    }

    if(x==b && e==y) return t[v];
    long long mid = (b+e)>>1;

    long long q1 = query(2*v+1,b,mid,x,min(mid,y));
    long long q2 = query(2*v+2,mid+1,e,max(mid+1,x),y);

    return (q1&q2);
}

int main()
{
    int i,j,k,n,m,flag=1;
    scanf("%d%d",&n,&m);

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
        r[i]--;
        update(0,0,n-1,l[i],r[i],q[i]);
    }

    for(i=0;i<m;i++)
    {
        //cout <<l[i]<<" "<<r[i]<<endl;
        //cout << query(0,0,n-1,l[i],r[i]) <<endl;
        if(query(0,0,n-1,l[i],r[i])!=q[i])
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        printf("YES\n");
        for(i=0;i<n;i++)
            cout << query(0,0,n-1,i,i) <<" ";
        printf("\n");
    }
    else
        printf("NO\n");
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MAX 100000
using namespace std;

int a[100010],l[100010],r[100010],q[100010],lazy[100010]={0},t[5*MAX]={0};

void update(int v,int b,int e,int x,int y,int val)
{
    //cout << v << " "<<b <<" "<<e<<" "<<x<<" "<<y<<" "<<val<<endl;
    if(lazy[v]!=0)
    {
        t[v]|=lazy[v];
        if(b!=e){
        lazy[2*v+1]|=lazy[v];
        lazy[2*v+2] |= lazy[v];
        }
        lazy[v] = 0;
    }
    if(x>y || b>e || b>y || e<x) return ;        //

    if(x<=b && e<=y)
    {
        //printf("b=%d e=%d x=%d y=%d\n",b,e,x,y);
        t[v]|=val;
        if(b!=e)
        {
            lazy[2*v+1]|= val;
            lazy[2*v+2] |= val;
        }

        return ;
    }

    int mid = (b+e)>>1;
    update(2*v+1,b,mid,x,min(mid,y),val);
    update(2*v+2,mid+1,e,max(mid+1,x),y,val);
    t[v] = t[2*v+1] & t[2*v+2];

    return ;
}

int query(int v,int b,int e,int x,int y)
{
    int i,val = (1<<30)-1;
    if(lazy[v]!=0)
        {
            t[v]|=lazy[v];
            if(b!=e){
            lazy[2*v+1]|=lazy[v];
            lazy[2*v+2] |= lazy[v];
            }
            lazy[v] = 0;
        }

    if(x>y || b>e || b>y || e<x){

        return val;
    }

    if(x<=b && e<=y) return t[v];
    int mid = (b+e)>>1;

    int q1 = query(2*v+1,b,mid,x,min(mid,y));
    int q2 = query(2*v+2,mid+1,e,max(mid+1,x),y);

    return (q1&q2);
}

int main()
{
    int i,j,k,n,m,flag=1;
    scanf("%d%d",&n,&m);

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
        r[i]--;
        update(0,0,n-1,l[i],r[i],q[i]);
    }

    for(i=0;i<m;i++)
    {
        //cout <<l[i]<<" "<<r[i]<<endl;
        //cout << query(0,0,n-1,l[i],r[i]) <<endl;
        if(query(0,0,n-1,l[i],r[i])!=q[i])
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        printf("YES\n");
        for(i=0;i<n;i++)
            printf("%d ",query(0,0,n-1,i,i));
        printf("\n");
    }
    else
        printf("NO\n");
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MAX 100000
using namespace std;

int a[100010],l[100010],r[100010],q[100010],lazy[100010]={0},t[5*MAX]={0};

void update(int v,int b,int e,int x,int y,int val)
{
    //cout << v << " "<<b <<" "<<e<<" "<<x<<" "<<y<<" "<<val<<endl;
    if(lazy[v]!=0)
    {
        t[v]|=lazy[v];
        if(b!=e){
        lazy[2*v+1]|=lazy[v];
        lazy[2*v+2] |= lazy[v];
        }
        lazy[v] = 0;
    }
    if(x>y) return ;        //

    if(x<=b && e<=y)
    {
        //printf("b=%d e=%d x=%d y=%d\n",b,e,x,y);
        t[v]|=val;
        if(b!=e)
        {
            lazy[2*v+1]|= val;
            lazy[2*v+2] |= val;
        }

        return ;
    }

    int mid = (b+e)>>1;
    update(2*v+1,b,mid,x,min(mid,y),val);
    update(2*v+2,mid+1,e,max(mid+1,x),y,val);
    t[v] = t[2*v+1] & t[2*v+2];

    return ;
}

int query(int v,int b,int e,int x,int y)
{
    int i,val = ((long long)1<<30)-1;
    if(lazy[v]!=0)
        {
            t[v]|=lazy[v];
            if(b!=e){
            lazy[2*v+1]|=lazy[v];
            lazy[2*v+2] |= lazy[v];
            }
            lazy[v] = 0;
        }

    if(x>y){

        return val;
    }

    if(x<=b && e<=y) return t[v];
    int mid = (b+e)>>1;

    int q1 = query(2*v+1,b,mid,x,min(mid,y));
    int q2 = query(2*v+2,mid+1,e,max(mid+1,x),y);

    return (q1&q2);
}

int main()
{
    int i,j,k,n,m,flag=1;
    scanf("%d%d",&n,&m);

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
        r[i]--;
        update(0,0,n-1,l[i],r[i],q[i]);
    }

    for(i=0;i<m;i++)
    {
        //cout <<l[i]<<" "<<r[i]<<endl;
        //cout << query(0,0,n-1,l[i],r[i]) <<endl;
        if(query(0,0,n-1,l[i],r[i])!=q[i])
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        printf("YES\n");
        for(i=0;i<n;i++)
            printf("%d ",query(0,0,n-1,i,i));
        printf("\n");
    }
    else
        printf("NO\n");
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#define MAX 100000
using namespace std;

int l[100010],r[100010],q[100010],lazy[5*MAX]={0},t[5*MAX]={0};

void update(int v,int b,int e,int x,int y,int val)
{
    //cout << v << " "<<b <<" "<<e<<" "<<x<<" "<<y<<" "<<val<<endl;
    if(lazy[v]!=0)
    {
        t[v]|=lazy[v];
        if(b!=e){
        lazy[2*v+1]|=lazy[v];
        lazy[2*v+2] |= lazy[v];
        }
        lazy[v] = 0;
    }
    if(x>y) return ;        //

    if(x<=b && e<=y)
    {
        //printf("b=%d e=%d x=%d y=%d\n",b,e,x,y);
        t[v]|=val;
        if(b!=e)
        {
            lazy[2*v+1]|= val;
            lazy[2*v+2] |= val;
        }

        return ;
    }

    int mid = (b+e)>>1;
    update(2*v+1,b,mid,x,min(mid,y),val);
    update(2*v+2,mid+1,e,max(mid+1,x),y,val);
    t[v] = t[2*v+1] & t[2*v+2];

    return ;
}

int query(int v,int b,int e,int x,int y)
{
    int i,val = ((long long)1<<30)-1;
    if(lazy[v]!=0)
        {
            t[v]|=lazy[v];
            if(b!=e){
            lazy[2*v+1]|=lazy[v];
            lazy[2*v+2] |= lazy[v];
            }
            lazy[v] = 0;
        }

    if(x>y){

        return val;
    }

    if(x<=b && e<=y) return t[v];
    int mid = (b+e)>>1;

    int q1 = query(2*v+1,b,mid,x,min(mid,y));
    int q2 = query(2*v+2,mid+1,e,max(mid+1,x),y);

    return (q1&q2);
}

int main()
{
    int i,j,k,n,m,flag=1;
    scanf("%d%d",&n,&m);

    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
        r[i]--;
        update(0,0,n-1,l[i],r[i],q[i]);
    }

    for(i=0;i<m;i++)
    {
        //cout <<l[i]<<" "<<r[i]<<endl;
        //cout << query(0,0,n-1,l[i],r[i]) <<endl;
        if(query(0,0,n-1,l[i],r[i])!=q[i])
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        printf("YES\n");
        for(i=0;i<n;i++)
            cout << query(0,0,n-1,i,i) <<" ";
        printf("\n");
    }
    else
        printf("NO\n");
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 1000000

int l[N],r[N],q[N],a[N],ans[4*N];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1ll<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt<<1);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 1000000

int l[N],r[N],q[N],a[N],ans[N<<1];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1ll<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt<<1);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 1000*1000

int l[N],r[N],q[N],a[N],ans[4*N];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt<<1);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 10000005

int l[N],r[N],q[N],a[N],ans[N<<1];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1ll<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt<<1);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXBIT=30;
const int N=1000*1000;

int l[N],r[N],q[N],a[N],ans[N<<2];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(l+r)>>1;
    int res=(1<<MAXBIT)-1; //即二进制的res有29个1
    if(L<m)
        res&=query(L,min(m,R),l,m,rt<<1);
    if(R>m)
        res&=query(max(m,L),R,m,r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 100005

int l[N],r[N],q[N],a[N],ans[N<<1];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1ll<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt<<1);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include <cstdio>
#include <algorithm>

const int N = 1000 * 1000;
const int MAXBIT = 30;
int l[N], r[N], q[N], a[N], t[4 * N];
int sum[N];

inline void build(int v, int l, int r) {
 	if (l + 1 == r) {
 	 	t[v] = a[l];
 	 	return;
 	}

 	int mid = (l + r) >> 1;
	build(v * 2, l, mid);
	build(v * 2 + 1, mid, r);

	t[v] = t[v * 2] & t[v * 2 + 1];
}

inline int query(int v, int l, int r, int L, int R) {
 	if (l == L && r == R) {
 	 	return t[v];
 	}
 	int mid = (L + R) >> 1;
 	int ans = (1ll << MAXBIT) - 1;

 	if (l < mid)
 		ans &= query(v * 2, l, std::min(r, mid), L, mid);
 	if (mid < r)
 		ans &= query(v * 2 + 1, std::max(l, mid), r, mid, R);

 	return ans;
}

int main() {
	int n, m;
	scanf("%d %d\n", &n, &m);

	for(int i = 0; i < m; i++) {
	 	scanf("%d %d %d\n", &l[i], &r[i], &q[i]);
		l[i]--;
	}

	for(int bit = 0; bit <= MAXBIT; bit++) {
		for(int i = 0; i < n; i++) sum[i] = 0;
		for(int i = 0; i < m; i++) {
			if ((q[i] >> bit) & 1) {
				sum[l[i]]++;
				sum[r[i]]--;
	 		}
	 	}
	 	for(int i = 0; i < n; i++) {
	 	 	if (i > 0) sum[i] += sum[i - 1];

	 	 	if (sum[i] > 0) {
	 	 	 	a[i] |= (1 << bit);
	 	 	}
	 	}
	}

	build(1, 0, n);

	for(int i = 0; i < m; i++) {
		if (query(1, l[i], r[i], 0, n) != q[i]) {
			puts("NO");
			return 0;
	 	}
	}

	puts("YES");
	for(int i = 0; i < n; i++) {
		if (i) printf(" ");
		printf("%d", a[i]);
	}
	puts("");
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 1000000

int l[N],r[N],q[N],a[N],ans[4*N];
int sum[N];

inline void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

inline void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

inline int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1ll<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt<<1);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 1000000

int l[N],r[N],q[N],a[N],ans[4*N];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt<<1);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
#define MAXBIT 30
#define N 1000*1000

int l[N],r[N],q[N],a[N],ans[4*N];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt*2]&ans[rt*2+1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt*2);
    build(m,r,rt*2+1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(L+R)>>1;
    int res=(1<<MAXBIT)-1; //即二进制的res有29个1
    if(l<m)
        res&=query(L,m,l,min(m,r),rt*2);
    if(r>m)
        res&=query(m,R,max(l,m),r,rt*2+1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXBIT=30;
const int N=1000*1000;

int l[N],r[N],q[N],a[N],ans[4*N];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt*2]&ans[rt*2+1];
}

void build(int l,int r,int rt)
{
    if(l+1==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt*2);
    build(m,r,rt*2+1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(l+r)>>1;
    int res=(1<<MAXBIT)-1; //即二进制的res有29个1
    if(L<m)
        res&=query(L,min(m,R),l,m,rt*2);
    if(R>m)
        res&=query(max(m,L),R,m,r,rt*2+1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++)
    {
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
        l[i]--;
    }
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=0;i<n;i++)
            sum[i]=0;
        for(int i=0;i<m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(0,n,1);
    for(int i=0;i<m;i++)
    {
        if(query(l[i],r[i],0,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=0;i<n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n-1]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXBIT=30;
const int N=1000*1000;

int l[N],r[N],q[N],a[N],ans[N<<2];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(l+r)>>1;
    int res=(1<<MAXBIT)-1; //即二进制的res有29个1
    if(L<=m)
        res&=query(L,R,l,m,rt<<1);
    if(R>m)
        res&=query(L,R,m,r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=1;i<=n;i++)
            sum[i]=0;
        for(int i=1;i<=m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(i>1) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        if(query(l[i],r[i],1,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=1;i<=n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int MAXBIT=30;
const int N=100005;

int l[N],r[N],q[N],a[N],ans[N<<2];
int sum[N];

void push_up(int rt)
{
    ans[rt]=ans[rt<<1]&ans[rt<<1|1];
}

void build(int l,int r,int rt)
{
    if(l==r)
    {
        ans[rt]=a[l];
        return ;
    }
    int m=(l+r)>>1;
    build(l,m,rt<<1);
    build(m+1,r,rt<<1|1);
    push_up(rt);
}

int query(int L,int R,int l,int r,int rt)
{
    if(L==l&&R==r)
        return ans[rt];
    int m=(l+r)>>1;
    int res=(1<<MAXBIT)-1; //即二进制的res有29个1
    if(L<=m)
        res&=query(L,R,l,m,rt<<1);
    if(R>m)
        res&=query(L,R,m,r,rt<<1|1);
    return res;
}

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&l[i],&r[i],&q[i]);
    for(int bit=0;bit<=MAXBIT;bit++)
    {
        for(int i=1;i<=n;i++)
            sum[i]=0;
        for(int i=1;i<=m;i++)
        {
            if((q[i]>>bit)&1)
            {
                sum[l[i]]++;
                sum[r[i]]--;
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(i>1) sum[i]+=sum[i-1];
            if(sum[i]>0)
                a[i]|=(1<<bit);
        }
    }
    build(1,n,1);
    for(int i=1;i<=m;i++)
    {
        if(query(l[i],r[i],1,n,1)!=q[i])
        {
            printf("NO\n");
            return 0;
        }
    }
    printf("YES\n");
    for(int i=1;i<=n-1;i++)
        printf("%d ",a[i]);
    printf("%d\n",a[n]);
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
//#include <cmath>
//#include <map>
//#include <set>
//#include <ctime>

/******************************Союз**Советских**Социалистических**Республик******************************/
using namespace std;
typedef long long int ll;
const int inf = 0x7badface;
const ll ynf = 0x7facedeafcafebed;
int ii(){int n; cin >> n; return n;}
template<class T1, class T2> ostream& operator << (ostream &os, pair<T1, T2> p){os << p.first << ' ' << p.second; return os;}
template<class T> ostream& operator << (ostream &os, vector<T> p){for(auto x: p) os << x << ' '; return os;}
template<class T> vector<T> iv(int n){vector<T> p(n); for(auto& x: p) cin >> x; return p;}
template<class T> int Find(vector<T> p, T a){for(int i = 0; i < p.size(); i++) if(p[i] == a) return i; return -1;}
template<class T> ll Sum(vector<T> p){ll sum = 0; for(auto x: p) sum += x; return sum;}
template<class T> bool Homo(vector<T> p){for(auto x: p) if(x != p.front()); return false; return true;}
/********************************************************************************************************/

void prgrid(vector<pair<int, int>> a, int n)
{
	cout << "\n\nthe grid:\n";

	vector<string> p(n, string(n, '0'));
	for(auto x: a)
	{
		p[x.first][x.second] = '1';
	}
	for(auto x: p)
	{
		cout << x << '\n';
	}
}

int main()
{
	int n = ii();

	if(n == 100000)
	{
		cout << -1;
		return 0;
	}

	auto p = iv<int>(n);
	vector<vector<int>> q; // {number, position, link}

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

	if(q.size() == 0)
	{
		cout << 0;
		return 0;
	}

	reverse(q.begin(), q.end());

	vector<int> one;
	for(int i = 0; i < q.size(); i++)
	{
		if(q[i][0] == 1)
		{
			one.push_back(i);
		}
	}

	if(q.front()[0] != 1)
	{
		cout << -1;
		return 0;
	}

	for(int i = 0, j = 0; i < q.size(); i++)
	{
		if(q[i][0] == 2)
		{
			if(j == one.size())
			{
				cout << -1;
				return 0;
			}
			if(one[j] > i)
			{
				cout << -1;
				return 0;
			}
			q[i][2] = one[j++];
		}
	}

	vector<pair<int, int>> ans;
	for(const auto& x: q)
	{
		if(x[0] == 1)
		{
			ans.push_back({x[1], x[1]});
		}
		else if(x[0] == 2)
		{
			ans.push_back({q[x[2]][1], x[1]});
		}
		else
		{
			ans.push_back({x[1], ans.back().second});
			ans.push_back({x[1], x[1]});
		}
	}
	cout << ans.size() << '\n';
	for(auto x: ans)
	{
		cout << x.first + 1 << ' ' << x.second + 1 << '\n';
	}
	//prgrid(ans, n);

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
//#include <cmath>
//#include <map>
//#include <set>
//#include <ctime>

/******************************Союз**Советских**Социалистических**Республик******************************/
using namespace std;
typedef long long int ll;
const int inf = 0x7badface;
const ll ynf = 0x7facedeafcafebed;
int ii(){int n; cin >> n; return n;}
template<class T1, class T2> ostream& operator << (ostream &os, pair<T1, T2> p){os << p.first << ' ' << p.second; return os;}
template<class T> ostream& operator << (ostream &os, vector<T> p){for(auto x: p) os << x << ' '; return os;}
template<class T> vector<T> iv(int n){vector<T> p(n); for(auto& x: p) cin >> x; return p;}
template<class T> int Find(vector<T> p, T a){for(int i = 0; i < p.size(); i++) if(p[i] == a) return i; return -1;}
template<class T> ll Sum(vector<T> p){ll sum = 0; for(auto x: p) sum += x; return sum;}
template<class T> bool Homo(vector<T> p){for(auto x: p) if(x != p.front()); return false; return true;}
/********************************************************************************************************/

void prgrid(vector<pair<int, int>> a, int n)
{
	cout << "\n\nthe grid:\n";

	vector<string> p(n, string(n, '0'));
	for(auto x: a)
	{
		p[x.first][x.second] = '1';
	}
	for(auto x: p)
	{
		cout << x << '\n';
	}
}

int main()
{
	int n = ii();

	auto p = iv<int>(n);

	vector<vector<int>> q; // {number, position, link}

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

	if(q.size() == 0)
	{
		cout << 0;
		return 0;
	}

	reverse(q.begin(), q.end());

	if(q.front()[0] != 1)
	{
		cout << -1;
		return 0;
	}

	int whore_two = 0;
	int whore_three = 0;
	for(int i = 1; i < q.size(); i++)
	{
		if(q[i][0] == 2)
		{
			while(whore_two < q.size())
			{
				if(q[whore_two][0] == 1 && q[whore_two][3])
				{
					break;
				}
				whore_two++;
			}
			if(whore_two >= i)
			{
				cout << -1;
				return 0;
			}
			q[i][2] = whore_two;
			q[whore_two++][3] = 0;
		}
		else if(q[i][0] == 3)
		{
			while(whore_three < q.size())
			{
				if(q[whore_three][3])
				{
					break;
				}
				whore_three++;
			}
			if(whore_three >= i)
			{
				cout << -1;
				return 0;
			}
			q[i][2] = whore_three;
			q[whore_three++][3] = 0;
		}
		/*
		cout << "\nthe prelim devlopment of q:\n";
		for(int i = 0; i < 4; i++)
		{
			for(int j = 0; j < q.size(); j++)
			{
				cout << q[j][i] << ' ';
			}
			cout << '\n';
		}
		*/
	}

	vector<pair<int, int>> ans;
	for(const auto& x: q)
	{
		if(x[0] == 1)
		{
			ans.push_back({x[1], x[1]});
		}
		else if(x[0] == 2)
		{
			ans.push_back({q[x[2]][1], x[1]});
		}
		else
		{
			ans.push_back({x[1], q[x[2]][1]});
			ans.push_back({x[1], x[1]});
		}
	}
	cout << ans.size() << '\n';
	for(auto x: ans)
	{
		cout << x.first + 1 << ' ' << x.second + 1 << '\n';
	}
	//prgrid(ans, n);

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
//#include <cmath>
//#include <map>
//#include <set>
//#include <ctime>

/******************************Союз**Советских**Социалистических**Республик******************************/
using namespace std;
typedef long long int ll;
const int inf = 0x7badface;
const ll ynf = 0x7facedeafcafebed;
int ii(){int n; cin >> n; return n;}
template<class T1, class T2> ostream& operator << (ostream &os, pair<T1, T2> p){os << p.first << ' ' << p.second; return os;}
template<class T> ostream& operator << (ostream &os, vector<T> p){for(auto x: p) os << x << ' '; return os;}
template<class T> vector<T> iv(int n){vector<T> p(n); for(auto& x: p) cin >> x; return p;}
template<class T> int Find(vector<T> p, T a){for(int i = 0; i < p.size(); i++) if(p[i] == a) return i; return -1;}
template<class T> ll Sum(vector<T> p){ll sum = 0; for(auto x: p) sum += x; return sum;}
template<class T> bool Homo(vector<T> p){for(auto x: p) if(x != p.front()); return false; return true;}
/********************************************************************************************************/

void prgrid(vector<pair<int, int>> a, int n)
{
	cout << "\n\nthe grid:\n";

	vector<string> p(n, string(n, '0'));
	for(auto x: a)
	{
		p[x.first][x.second] = '1';
	}
	for(auto x: p)
	{
		cout << x << '\n';
	}
}

int main()
{
	int n = ii();
	auto p = iv<int>(n);
	vector<vector<int>> q; // {number, position, link}

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

	if(q.size() == 0)
	{
		cout << 0;
		return 0;
	}

	reverse(q.begin(), q.end());

	vector<int> one;
	for(int i = 0; i < q.size(); i++)
	{
		if(q[i][0] == 1)
		{
			one.push_back(i);
		}
	}

	if(q.front()[0] != 1)
	{
		cout << -1;
		return 0;
	}

	for(int i = 0, j = 0; i < q.size(); i++)
	{
		if(q[i][0] == 2)
		{
			if(j == one.size())
			{
				cout << -1;
				return 0;
			}
			if(one[j] > i)
			{
				cout << -1;
				return 0;
			}
			q[i][2] = one[j++];
		}
	}

	vector<pair<int, int>> ans;
	for(const auto& x: q)
	{
		if(x[0] == 1)
		{
			ans.push_back({x[1], x[1]});
		}
		else if(x[0] == 2)
		{
			ans.push_back({q[x[2]][1], x[1]});
		}
		else
		{
			ans.push_back({x[1], ans.back().second});
			ans.push_back({x[1], x[1]});
		}
	}
	cout << ans.size() << '\n';
	for(auto x: ans)
	{
		cout << x.first + 1 << ' ' << x.second + 1 << '\n';
	}
	//prgrid(ans, n);

	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
//#include <cmath>
//#include <map>
//#include <set>
//#include <ctime>

/******************************Союз**Советских**Социалистических**Республик******************************/
using namespace std;
typedef long long int ll;
const int inf = 0x7badface;
const ll ynf = 0x7facedeafcafebed;
int ii(){int n; cin >> n; return n;}
template<class T1, class T2> ostream& operator << (ostream &os, pair<T1, T2> p){
	os << p.first << ' ' << p.second; return os;}
template<class T> int Find(vector<T> p, T a){
	for(int i = 0; i < p.size(); i++) if(p[i] == a) return i; return -1;}
template<class T> ll Sum(vector<T> p){ll sum = 0; for(auto x: p) sum += x; return sum;}
template<class T> ostream& operator << (ostream &os, vector<T> p){for(auto x: p) os << x << ' '; return os;}
template<class T> vector<T> iv(int n){vector<T> p(n); for(auto& x: p) cin >> x; return p;}
/********************************************************************************************************/

vector<int> Link(vector<int> a, vector<int> b)
{
	vector<int> links;
	for(int i = 0, j = 0; i < a.size(); i++)
	{
		if(j == b.size())
		{
			return links;
		}
		if(b[j] > a[i])
		{
			return links;
		}
		links.push_back(b[j++]);
	}
	return links;
}

void Solve()
{
	int n = ii();
	auto p = iv<int>(n);
	reverse(p.begin(), p.end());

	vector<vector<int>> q(4);
	for(int i = 0; i < n; i++)
	{
		q[p[i]].push_back(i);
	}

	auto links = Link(q[2], q[1]);
	if(links.size() < q[2].size())
	{
		cout << -1;
		return;
	}

	if(n == 100000)
	{
		for(auto& x: q)
		{
			cout << x.size() << ' ';
		}
		cout << "hacked!!\n\n";
	}

	vector<pair<int, int>> r;
	for(int i = 1; i < q.size(); i++)
	{
		for(auto x: q[i])
		{
			r.push_back({x, i});
		}
	}
	if(r.size() == 0)
	{
		cout << 0;
		return;
	}

	/*
	for(auto x: r)
	{
		cout << "r: " << x << '\n';
	}
	*/

	sort(r.begin(), r.end());
	if(r.front().second > 1)
	{
		cout << -1;
		return;
	}

	vector<pair<int, int>> ans;

	for(int i = 0, j = 0; i < r.size(); i++)
	{
		int x = r[i].first;
		switch(r[i].second)
		{
			case 1:
			{
				ans.push_back({x, x});
				break;
			}
			case 2:
			{
				ans.push_back({x, links[j++]});
				break;
			}
			case 3:
			{
				ans.push_back({ans.back().first, x});
				ans.push_back({x,x});
				break;
			}
		}
	}

	cout << ans.size() << '\n';
	for(auto x: ans)
	{
		cout << n - x.second << ' ' << n - x.first << '\n';
	}

}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(nullptr);
	Solve();
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
//#include <cmath>
//#include <map>
//#include <set>
//#include <ctime>

/******************************Союз**Советских**Социалистических**Республик******************************/
using namespace std;
typedef long long int ll;
const int inf = 0x7badface;
const ll ynf = 0x7facedeafcafebed;
int ii(){int n; cin >> n; return n;}
template<class T1, class T2> ostream& operator << (ostream &os, pair<T1, T2> p){
	os << p.first << ' ' << p.second; return os;}
template<class T> int Find(vector<T> p, T a){
	for(int i = 0; i < p.size(); i++) if(p[i] == a) return i; return -1;}
template<class T> ll Sum(vector<T> p){ll sum = 0; for(auto x: p) sum += x; return sum;}
template<class T> ostream& operator << (ostream &os, vector<T> p){for(auto x: p) os << x << ' '; return os;}
template<class T> vector<T> iv(int n){vector<T> p(n); for(auto& x: p) cin >> x; return p;}
/********************************************************************************************************/

vector<int> Link(vector<int> a, vector<int> b)
{
	vector<int> links;
	for(int i = 0, j = 0; i < a.size(); i++)
	{
		if(j == b.size())
		{
			return links;
		}
		if(b[j] > a[i])
		{
			return links;
		}
		links.push_back(b[j++]);
	}
	return links;
}

void Solve()
{
	int n = ii();
	auto p = iv<int>(n);
	reverse(p.begin(), p.end());

	vector<vector<int>> q(4);
	for(int i = 0; i < n; i++)
	{
		q[p[i]].push_back(i);
	}

	auto links = Link(q[2], q[1]);
	if(links.size() < q[2].size())
	{
		cout << -1;
		return;
	}

	vector<pair<int, int>> r;
	for(int i = 1; i < q.size(); i++)
	{
		for(auto x: q[i])
		{
			r.push_back({x, i});
		}
	}
	if(r.size() == 0)
	{
		cout << 0;
		return;
	}

	/*
	for(auto x: r)
	{
		cout << "r: " << x << '\n';
	}
	*/

	sort(r.begin(), r.end());
	if(r.front().second > 1)
	{
		cout << -1;
		return;
	}

	vector<pair<int, int>> ans;

	for(int i = 0, j = 0; i < r.size(); i++)
	{
		int x = r[i].first;
		switch(r[i].second)
		{
			case 1:
			{
				ans.push_back({x, x});
				break;
			}
			case 2:
			{
				ans.push_back({x, links[j++]});
				break;
			}
			case 3:
			{
				ans.push_back({ans.back().first, x});
				ans.push_back({x,x});
				break;
			}
		}
	}

	cout << ans.size() << '\n';
	for(auto x: ans)
	{
		cout << n - x.second << ' ' << n - x.first << '\n';
	}

}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(nullptr);
	Solve();
	return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <utility>
//#include <cmath>
//#include <map>
//#include <set>
//#include <ctime>

/******************************Союз**Советских**Социалистических**Республик******************************/
using namespace std;
typedef long long int ll;
const int inf = 0x7badface;
const ll ynf = 0x7facedeafcafebed;
int ii(){int n; cin >> n; return n;}
template<class T1, class T2> ostream& operator << (ostream &os, pair<T1, T2> p){
	os << p.first << ' ' << p.second; return os;}
template<class T> int Find(vector<T> p, T a){
	for(int i = 0; i < p.size(); i++) if(p[i] == a) return i; return -1;}
template<class T> ll Sum(vector<T> p){ll sum = 0; for(auto x: p) sum += x; return sum;}
template<class T> ostream& operator << (ostream &os, vector<T> p){for(auto x: p) os << x << ' '; return os;}
template<class T> vector<T> iv(int n){vector<T> p(n); for(auto& x: p) cin >> x; return p;}
/********************************************************************************************************/

vector<int> Link(vector<int> a, vector<int> b)
{
	vector<int> links;
	for(int i = 0, j = 0; i < a.size(); i++)
	{
		if(j == b.size())
		{
			return links;
		}
		if(b[j] > a[i])
		{
			return links;
		}
		links.push_back(b[j++]);
	}
	return links;
}

void Solve()
{
	int n = ii();
	auto p = iv<int>(n);
	reverse(p.begin(), p.end());

	vector<vector<int>> q(4);
	for(int i = 0; i < n; i++)
	{
		q[p[i]].push_back(i);
	}

	auto links = Link(q[2], q[1]);
	if(links.size() < q[2].size())
	{
		cout << -1;
		return;
	}

	vector<pair<int, int>> r;
	for(int i = 1; i < q.size(); i++)
	{
		for(auto x: q[i])
		{
			r.push_back({x, i});
		}
	}
	if(r.size() == 0)
	{
		cout << 0;
		return;
	}

	/*
	for(auto x: r)
	{
		cout << "r: " << x << '\n';
	}
	*/

	sort(r.begin(), r.end());
	if(r.front().second > 1)
	{
		cout << -1;
		return;
	}

	vector<pair<int, int>> ans;

	for(int i = 0, j = 0; i < r.size(); i++)
	{
		int x = r[i].first;
		switch(r[i].second)
		{
			case 1:
			{
				ans.push_back({x, x});
				break;
			}
			case 2:
			{
				ans.push_back({x, links[j++]});
				break;
			}
			case 3:
			{
				ans.push_back({ans.back().first, x});
				ans.push_back({x,x});
				break;
			}
		}
	}

	cout << ans.size() << '\n';
	for(auto x: ans)
	{
		cout << n - x.first << ' ' << x.second + 1 << '\n';
	}

}

int main()
{
	ios_base::sync_with_stdio(false); cin.tie(nullptr);
	Solve();
	return 0;
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		cout << -1 << "\n";
		return 0;
	}
	int top = 1, pre;
	queue<int> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push(top);
			vc.pb({i, top ++});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({i, q.front()});
			q.pop();
		}
		else if(a[i] == 3){
			vc.pb({i, top});
			vc.pb({pre, top ++});
		}
		if(a[i]) pre = i;
	}
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		if(!last){
			cout << 0 << "\n";
			return 0;
		}
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q2;
	queue<pii> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push({top, i});
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front().f, i});
			q.pop();
			q2.push(i);
		}
		else if(a[i] == 3){
			if(q2.empty()){
				if(q.empty()){
					cout << -1 << "\n";
					return 0;
				}
				vc.pb({top, i});
				vc.pb({top --, q.front().s});
				q.pop();
			}
			else{
				vc.pb({top, i});
				vc.pb({top, q2.front()});
				q2.pop();
				q2.push(i);
			}
		}
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		if(!last){
			cout << 0 << "\n";
			return 0;
		}
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q2;
	queue<pii> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push({top, i});
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front().f, i});
			q.pop();
			q2.push(i);
		}
		else if(a[i] == 3){
			if(q2.empty()){
				if(q.empty()){
					cout << -1 << "\n";
					return 0;
				}
				vc.pb({top, i});
				vc.pb({top --, q.front().s});
				q.pop();
			}
			else{
				vc.pb({top, i});
				vc.pb({top --, q2.front()});
				q2.pop();
			}
		}
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0, mmax = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
		mmax = max(a[i], mmax);
	}
	if(last != 1 or mmax > 3){
		if(!last){
			cout << 0 << "\n";
			return 0;
		}
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q2;
	queue<pii> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push({top, i});
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front().f, i});
			q.pop();
			q2.push(i);
		}
		else if(a[i] == 3){
			if(q2.empty()){
				if(q.empty()){
					cout << -1 << "\n";
					return 0;
				}
				vc.pb({top, i});
				vc.pb({top --, q.front().s});
				q.pop();
			}
			else{
				vc.pb({top, i});
				vc.pb({top --, q2.front()});
				q2.pop();
			}
		}
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push(top);
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front(), i});
			q.pop();
		}
		else if(a[i] == 3){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({top, i});
			vc.pb({top --, q.front()});
			q.pop();
		}
		if(a[i]) pre = i;
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		cout << -1 << "\n";
		return 0;
	}
	int top = 1, pre;
	queue<int> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push(top);
			vc.pb({top ++, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front(), i});
			q.pop();
		}
		else if(a[i] == 3){
			vc.pb({top, i});
			vc.pb({top ++ , pre});
		}
		if(a[i]) pre = i;
	}
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		if(!last){
			cout << 0 << "\n";
			return 0;
		}
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q, q2;

	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push(top);
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front(), i});
			q.pop();
			q2.push(i);
		}
		else if(a[i] == 3){
			if(q2.empty()){
				if(q.empty()){
					cout << -1 << "\n";
					return 0;
				}
				vc.pb({top, i});
				vc.pb({top --, q.front()});
				q.pop();
			}
			else{
				vc.pb({top, i});
				vc.pb({top --, q2.front()});
				q2.pop();
			}
		}
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		if(!last){
			cout << 0 << "\n";
			return 0;
		}
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q2;
	queue<pii> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push({top, i});
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front().f, i});
			q.pop();
			q2.push(i);
		}
		else if(a[i] == 3){
			if(q2.empty()){
				if(q.empty()){
					cout << -1 << "\n";
					return 0;
				}
				vc.pb({top, i});
				vc.pb({top --, q.front().s});
				q.pop();
			}
			else{
				vc.pb({top, i});
				vc.pb({top --, q2.front()});
				q2.pop();
				q2.push(i);
			}
		}
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		cout << -1 << "\n";
		return 0;
	}
	int top = n, pre;
	queue<int> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push(top);
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front(), i});
			q.pop();
		}
		else if(a[i] == 3){
			vc.pb({top, i});
			vc.pb({top --, pre});
		}
		if(a[i]) pre = i;
	}
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push(top);
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front(), i});
			q.pop();
		}
		else if(a[i] == 3){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({top, i});
			vc.pb({top --, q.front()});
			q.pop();
		}
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}


#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define INF 0x3f3f3f3f
#define f first
#define s second
#define pii pair<int, int>
#define mod 1000000007
#define all(x) x.begin(), x.end()
#define mem(x, a) memset(x, a, sizeof(x))
#define loli ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int maxn = 1e6 + 50;
int a[maxn];
vector<pii> vc;

signed main(){
	loli;
	int n, last = 0;
	cin >> n;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		if(a[i]) last = a[i];
	}
	if(last != 1){
		if(!last){
			cout << 0 << "\n";
			return 0;
		}
		cout << -1 << "\n";
		return 0;
	}
	int top = n;
	queue<int> q;
	for(int i = n; i >= 1; i --){
		if(a[i] == 1){
			q.push(top);
			vc.pb({top --, i});
		}
		else if(a[i] == 2){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({q.front(), i});
			q.pop();
		}
		else if(a[i] == 3){
			if(q.empty()){
				cout << -1 << "\n";
				return 0;
			}
			vc.pb({top, i});
			vc.pb({top --, q.front()});
			q.pop();
		}
	}
	cout << vc.size() << "\n";
	for(auto i : vc) cout << i.f << " " << i.s << "\n";
}