#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <math.h>
#include <queue>
#include <vector>
#include <set>


using namespace std;
struct UnionFind {
    vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

    UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化
        for(int i = 0; i < N; i++) par[i] = i;
    }

    int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
        if (par[x] == x) return x;
        return par[x] = root(par[x]);
    }

    void unite(int x, int y) { // xとyの木を併合
        int rx = root(x); //xの根をrx
        int ry = root(y); //yの根をry
        if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
        par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
    }

    bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }
};

template<class T> inline bool chmin(T& a, T b) {
  //aの方が大きければbに値を更新、そうでなければ何もしない
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template<class T> inline bool chmax(T& a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
bool compare_a_big(pair<int,int> l,pair<int,int> r){
  //firstが大きい方からソート、firstが同じならbが小さい方から
  if(l.first != r.first){
    return l.first>r.first;
  }
  else{
    return l.second < r.second;
  }
}
bool compare_a_b_big(pair<int,int> l,pair<int,int> r){
  //firstが大きい方からソート、firstが同じならbが大きい方から
  if(l.first != r.first){
    return l.first>r.first;
  }
  else{
    return l.second > r.second;
  }
}
bool compare_b_small(pair<int,int> l,pair<int,int> r){
  //secondが小さい方からソート、firstが同じならfirstが小さい方から
  if(l.second != r.second){
    return l.second<r.second;
  }
  else{
    return l.first < r.first;
  }
}
const int INF = 1e9;
const int M = 1000000007;


typedef long long int ll;
vector<ll> fac(300001); //n!(mod M)
vector<ll> ifac(300001); //k!^{M-2} (mod M)
//a,bの範囲的にこれだけ配列を用意していけば十分

ll mpow(ll x, ll n){ //x^n(mod M) ←普通にpow(x,n)では溢れてしまうため，随時mod計算
    ll ans = 1;
    while(n != 0){
        if(n&1) ans = ans*x % M;
        x = x*x % M;
        n = n >> 1;
    }
    return ans;
}

ll comb(ll a, ll b){ //aCbをmod計算、a,b<=300000でないと使えない
    fac[0] = 1;
    ifac[0] = 1;
    for(ll i = 0; i<300000; i++){
        fac[i+1] = fac[i]*(i+1) % M; // n!(mod M)
        ifac[i+1] = ifac[i]*mpow(i+1, M-2) % M; // k!^{M-2} (mod M) ←累乗にmpowを採用
    }
    if(a == 0 && b == 0)return 1;
    if(a < b || a < 0)return 0;
    ll tmp = ifac[a-b]* ifac[b] % M;
    return tmp * fac[a] % M;
}

typedef long long int ll;

int pow(int a,int b){
  if(b==0) return 1;
  else{
    return a*pow(a,b-1);

  }
}


int main(){
  int n,m;
  cin >> n >> m;
  int s[m],c[m];
  int i;
  for(i=0;i<m;i++){
    cin >> s[i] >> c[i];
  }
  int ans[n];
  for(i=0;i<n;i++){
    ans[i] = 10;
  }
  int isfalse = 0;
  for(i=0;i<m;i++){
    if(ans[s[i]-1] > 9){
      ans[s[i]-1] = c[i];
    }
    else{
      if(ans[s[i]-1] != c[i]){
        isfalse = 1;
      }
    }

  }
  if(isfalse){
    cout << -1 << endl;
  }
  else if(n>1&&ans[0]==0){
    cout << -1 << endl;
  }
  else if(n==1 && m==0){
    cout << 0 << endl;
  }
  else{
    int num = 0;
    for(i=0;i<n;i++){
      if(ans[n-1-i]==10 && i == n-1) num += pow(10,i);
      else if(ans[n-1-i]!=10)  num += ans[n-1-i]*pow(10,i);

    }

    cout << num << endl;
  }



}


Measured memory_bytes: 4992