package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
	"unsafe"
)

func main() {
	NM := sc.nextInts()
	N := NM[0]
	M := NM[1]

	maps := make(map[int]int)
	for i := 0; i < N; i++ {
		maps[i] = 0
	}

	for i := 0; i < M; i++ {
		tm := sc.nextInts()
		m := tm[0] - 1
		n := tm[1]

		if m == 0 && n == 0 {
			continue
		}

		if maps[m] > n {
			maps[m] = n
		}

		if maps[m] == 0 {
			maps[m] = n
		}
	}

	var ans int
	tmp := len(maps)

	for i := 0; i < N; i++ {
		v := maps[i]
		ans += v * powInt(10, tmp-1)
		tmp--
	}

	// for k, v := range maps {
	// 	ans += v * powInt(10, tmp-k-1)
	// }
	if maps[0] == 0 && len(maps) == 0 {
		fmt.Println(1)
	} else if maps[0] == 0 {
		fmt.Println(-1)
	} else {
		fmt.Println(ans)
	}
	// arr := make([]int, N)

	// for i := 0; i < N; i++ {
	// 	arr[i] = 10
	// }

	// for i := 0; i < M; i++ {
	// 	tm := sc.nextInts()
	// 	m := tm[0] - 1
	// 	n := tm[1]

	// 	var tmpMin int

	// 	if m == 0 {
	// 		if n == 0 {
	// 			tmpMin = arr[m]
	// 		} else {
	// 			if n < arr[m] {
	// 				tmpMin = n
	// 			} else {
	// 				tmpMin = arr[m]
	// 			}
	// 		}
	// 	} else {
	// 		if n < arr[m] {
	// 			tmpMin = n
	// 		} else {
	// 			tmpMin = arr[m]
	// 		}
	// 	}
	// 	arr[m] = tmpMin
	// }

	// for i := 0; i < N; i++ {
	// 	if arr[i] >= 10 {
	// 		arr[i] = 0
	// 	}
	// }
	// if arr[0] == 0 && len(arr) == 1 {
	// 	fmt.Println(1)
	// } else if arr[0] == 0 || len(arr) > N {
	// 	fmt.Println(-1)
	// } else {
	// 	tmp := len(arr)
	// 	ans := 0
	// 	for _, v := range arr {
	// 		ans += v * powInt(10, tmp-1)
	// 		tmp--
	// 	}
	// 	fmt.Println(ans)
	// }
}

/* template functions */
var (
	sc scanner
)

func init() {
	sc = scanner{
		buf: make([]string, 0, 0),
		cur: 0,
		r:   bufio.NewReader(os.Stdin),
	}
}

type scanner struct {
	buf []string
	cur int
	r   *bufio.Reader
}

func (s *scanner) readln() {
	rbuf := make([]byte, 0, 0)
	for {
		line, prefix, err := s.r.ReadLine()
		if err != nil {
			panic(err)
		}
		rbuf = append(rbuf, line...)
		if prefix == false {
			break
		}
	}
	s.cur = 0
	s.buf = strings.Split(*(*string)(unsafe.Pointer(&rbuf)), " ")
}
func (s *scanner) isFull() bool {
	if s.cur == len(s.buf) {
		return true
	}
	return false
}
func (s *scanner) resetCur() {
	s.cur = 0
}
func (s *scanner) next() string {
	if s.cur == 0 {
		s.readln()
	}
	res := s.buf[s.cur]
	s.cur++
	if s.isFull() {
		s.resetCur()
	}
	return res
}
func (s *scanner) nexts() []string {
	s.readln()
	s.resetCur()
	return s.buf
}
func (s *scanner) nextInt() int {
	if s.cur == 0 {
		s.readln()
	}
	res, _ := strconv.Atoi(s.buf[s.cur])
	s.cur++
	if s.isFull() {
		s.resetCur()
	}
	return res
}
func (s *scanner) nextInts() []int {
	s.readln()
	res := make([]int, len(s.buf))
	for i := range s.buf {
		res[i], _ = strconv.Atoi(s.buf[i])
	}
	s.resetCur()
	return res
}
func (s *scanner) nextFloat() float64 {
	if s.cur == 0 {
		s.readln()
	}
	res, _ := strconv.ParseFloat(s.buf[s.cur],
		64)
	s.cur++
	if s.isFull() {
		s.resetCur()
	}
	return res
}
func (s *scanner) nextFloats() []float64 {
	s.readln()
	res := make([]float64, len(s.buf))
	for i := range s.buf {
		res[i], _ = strconv.ParseFloat(s.buf[i],
			64)
	}
	s.resetCur()
	return res
}
func digits(x int) int {
	return len(strconv.Itoa(x))
}
func powInt(x, p int) (result int) {
	result = 1
	for i := 0; i < p; i++ {
		result *= x
	}
	return
}
func max(x, y int) int {
	return int(math.Max(float64(x), float64(y)))
}
func min(x, y int) int {
	return int(math.Min(float64(x), float64(y)))
}
func abs(x int) int {
	return int(math.Abs(float64(x)))
}
func varDump(value ...interface{}) {
	for _, v := range value {
		fmt.Fprintf(os.Stderr, "%#v\n", v)
	}
}
func yes() {
	fmt.Println("Yes")
}
func no() {
	fmt.Println("No")
}
