// #pragma GCC optimize "trapv" Uncomment when dealing with huge numbers
/*<----------PBDS---------->

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
template <typename T>
using order_set = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

order_set<datatype>oset;
Kth smallest : *oset.find_by_order(k-1); // 0 based index
No of elements less than k : oset.order_of_key(k);
Erase X : oset.erase(x)
<----------PBDS---------->*/
#include<iostream>
#include<bits/stdc++.h>
#define int long long
#define mod 1000000007
#define pb(x) push_back(x)
#define gcd(a,b) __gcd(a,b)
#define all(v) v.begin(),v.end()
#define lcm(a,b) (a*b)/gcd(a,b)
#define bits(x) __builtin_popcountll(x)
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
int32_t main()
{
		if(n==1 && m==0){
			cout<<"0";
			return 0;
		}
		int n,m; 
		cin >> n >> m;
		int a[n+1];
		memset(a,0,sizeof(a));
		bool can=true;
		vector<int>vis(n,0);
		int p=m;
		while(p--)
		{
			int x,y; 
			cin >> x >> y;
			x--;
			if(vis[x] && y!=a[x])
			{
				can=false; break;
			}
			vis[x]=1;
			a[x]=y;
		}
		string l="";
		if(!vis[0])
		{
			a[0]=1;
		}
		for(int i=0;i<n;i++)
		{
			l+=(a[i]+'0');
		}
 
		if(l.length()<n ||l.length()>n|| can==false || (l[0]=='0' && n!=1))
		{
			cout<<-1;return 0;
		}
		cout<<l;
}